diff options
-rw-r--r-- | FrontEnd/src/locales/en/translation.json | 1 | ||||
-rw-r--r-- | FrontEnd/src/locales/zh/translation.json | 1 | ||||
-rw-r--r-- | FrontEnd/src/views/settings/index.tsx | 104 | ||||
-rw-r--r-- | FrontEnd/src/views/timeline/Timeline.css | 4 |
4 files changed, 64 insertions, 46 deletions
diff --git a/FrontEnd/src/locales/en/translation.json b/FrontEnd/src/locales/en/translation.json index ac6d3762..9c6747e1 100644 --- a/FrontEnd/src/locales/en/translation.json +++ b/FrontEnd/src/locales/en/translation.json @@ -184,6 +184,7 @@ "changeAvatar": "Change avatar.", "changeNickname": "Change nickname.", "changeBookmarkVisibility": "Change bookmark visibility.", + "myRegisterCode": "My register code:", "dialogChangePassword": { "title": "Change Password", "prompt": "You are changing your password. You need to input the correct old password. After change, you need to login again and all old login will be invalid.", diff --git a/FrontEnd/src/locales/zh/translation.json b/FrontEnd/src/locales/zh/translation.json index 52a58146..130ebe66 100644 --- a/FrontEnd/src/locales/zh/translation.json +++ b/FrontEnd/src/locales/zh/translation.json @@ -184,6 +184,7 @@ "changeAvatar": "更改头像", "changeNickname": "更改昵称", "changeBookmarkVisibility": "修改书签时间线可见性", + "myRegisterCode": "我的注册码:", "dialogChangePassword": { "title": "修改密码", "prompt": "您正在修改密码,您需要输入正确的旧密码。成功修改后您需要重新登陆,而且以前所有的登录都会失效。", diff --git a/FrontEnd/src/views/settings/index.tsx b/FrontEnd/src/views/settings/index.tsx index 8110002b..633bb209 100644 --- a/FrontEnd/src/views/settings/index.tsx +++ b/FrontEnd/src/views/settings/index.tsx @@ -16,6 +16,7 @@ import ChangeAvatarDialog from "./ChangeAvatarDialog"; import ChangeNicknameDialog from "./ChangeNicknameDialog"; import "./index.css"; +import classNames from "classnames"; interface SettingSectionProps { title: I18nText; @@ -35,91 +36,106 @@ const SettingSection: React.FC<SettingSectionProps> = ({ title, children }) => { ); }; -interface ButtonSettingItemProps { +interface SettingItemContainerWithoutChildrenProps { title: I18nText; subtext?: I18nText; - onClick: () => void; first?: boolean; danger?: boolean; + style?: React.CSSProperties; + className?: string; + onClick?: () => void; } -const ButtonSettingItem: React.FC<ButtonSettingItemProps> = ({ +interface SettingItemContainerProps + extends SettingItemContainerWithoutChildrenProps { + children?: React.ReactNode; +} + +function SettingItemContainer({ title, subtext, - onClick, first, danger, -}) => { + children, + style, + className, + onClick, +}: SettingItemContainerProps): JSX.Element { const { t } = useTranslation(); return ( <div + style={style} className={classnames( - "settings-item clickable", + "row settings-item mx-0", first && "first", - danger && "cru-color-danger" + className )} - onClick={onClick} > - {convertI18nText(title, t)} - {subtext && ( + <div className="px-0 col col-12 col-sm-auto" onClick={onClick}> + <div className={classNames(danger && "cru-color-danger")}> + {convertI18nText(title, t)} + </div> <small className="d-block cru-color-secondary"> {convertI18nText(subtext, t)} </small> - )} + </div> + <div className="col col-12 col-sm-auto">{children}</div> </div> ); +} + +type ButtonSettingItemProps = SettingItemContainerWithoutChildrenProps; + +const ButtonSettingItem: React.FC<ButtonSettingItemProps> = ({ + className, + ...props +}) => { + return ( + <SettingItemContainer + className={classNames("clickable", className)} + {...props} + /> + ); }; -interface SelectSettingItemProps { - title: I18nText; - subtext?: I18nText; +interface SelectSettingItemProps + extends SettingItemContainerWithoutChildrenProps { options: { value: string; label: I18nText; }[]; value?: string; onSelect: (value: string) => void; - first?: boolean; } const SelectSettingsItem: React.FC<SelectSettingItemProps> = ({ - title, - subtext, options, value, onSelect, - first, + ...props }) => { const { t } = useTranslation(); return ( - <div className={classnames("row settings-item mx-0", first && "first")}> - <div className="px-0 col col-12 col-sm-auto"> - <div>{convertI18nText(title, t)}</div> - <small className="d-block cru-color-secondary"> - {convertI18nText(subtext, t)} - </small> - </div> - <div className="col col-12 col-sm-auto"> - {value == null ? ( - <Spinner /> - ) : ( - <select - value={value} - onChange={(e) => { - onSelect(e.target.value); - }} - > - {options.map(({ value, label }) => ( - <option key={value} value={value}> - {convertI18nText(label, t)} - </option> - ))} - </select> - )} - </div> - </div> + <SettingItemContainer {...props}> + {value == null ? ( + <Spinner /> + ) : ( + <select + value={value} + onChange={(e) => { + onSelect(e.target.value); + }} + > + {options.map(({ value, label }) => ( + <option key={value} value={value}> + {convertI18nText(label, t)} + </option> + ))} + </select> + )} + </SettingItemContainer> ); }; diff --git a/FrontEnd/src/views/timeline/Timeline.css b/FrontEnd/src/views/timeline/Timeline.css index b65ab3a0..4dd4fdcc 100644 --- a/FrontEnd/src/views/timeline/Timeline.css +++ b/FrontEnd/src/views/timeline/Timeline.css @@ -4,7 +4,7 @@ width: 100%; } -@keyframes timeline-line-node-noncurrent { +@keyframes timeline-line-node { to { box-shadow: 0 0 20px 3px var(--cru-primary-l1-color); } @@ -103,7 +103,7 @@ box-sizing: border-box; z-index: 1; animation: 1s infinite alternate; - animation-name: timeline-line-node-noncurrent; + animation-name: timeline-line-node; } .timeline-line .node-loading-edge { color: var(--cru-primary-color); |