feat: contact verification switch

This commit is contained in:
Tristan Yang
2023-05-15 15:39:26 +08:00
parent 110b0891ad
commit d00359d742
8 changed files with 85 additions and 38 deletions
+7 -1
View File
@@ -6,7 +6,7 @@
"nav": {
"general": "General",
"overview": "Overview",
"members": "Contacts",
"members": "Members",
"auto_delete_msg": "Auto-delete Messages",
"user": "User",
"my_account": "My Account",
@@ -88,6 +88,12 @@
"desc": "message self send on the left or right",
"left": "Left",
"self_right": "Self Right"
},
"contact_verify": {
"title": "Contact Verification",
"desc": "Toggle contact verification",
"enable": "Enable",
"disable": "Disable"
}
},
"license": {
+1 -1
View File
@@ -1,6 +1,6 @@
{
"chat": "聊天",
"members": "联系人",
"members": "成员",
"favs": "收藏",
"files": "文件",
"setting": "设置",
+2 -2
View File
@@ -12,8 +12,8 @@
"current_pwd": "当前密码",
"new_pwd": "新密码",
"confirm_new_pwd": "确认密码",
"manage_members": "联系人管理",
"manage_tip": "请在此管理你的联系人",
"manage_members": "成员管理",
"manage_tip": "请在此管理你的成员",
"admin": "管理员",
"user": "普通用户",
"copy_email": "复制邮箱",
+7 -1
View File
@@ -6,7 +6,7 @@
"nav": {
"general": "通用",
"overview": "概况",
"members": "联系人",
"members": "成员",
"auto_delete_msg": "自动删除消息",
"my_account": "我的账号",
"config": "配置",
@@ -82,6 +82,12 @@
"desc": "你可以决定自己发的消息居左还是居右",
"left": "居左",
"self_right": "居右"
},
"contact_verify": {
"title": "联系人验证",
"desc": "是否开启联系人验证",
"enable": "开启",
"disable": "关闭"
}
},
"license": {
+2 -4
View File
@@ -1,17 +1,15 @@
import { useState, useEffect } from "react";
import { StoredUser } from "../../app/slices/users";
import { useAppSelector } from "../../app/store";
import { compareVersion } from "../utils";
export default function useFilteredUsers() {
const [input, setInput] = useState("");
const { originUsers, serverVersion } = useAppSelector((store) => {
const { originUsers, enableContact } = useAppSelector((store) => {
return {
enableContact: store.server.contact_verification_enable,
originUsers: Object.values(store.users.byId),
serverVersion: store.server.version
};
});
const enableContact = compareVersion(serverVersion, "0.3.7") >= 0;
const [filteredUsers, setFilteredUsers] = useState<StoredUser[]>([]);
const users = enableContact ? originUsers.filter((u) => u.status == "added") : originUsers;
useEffect(() => {
+17 -26
View File
@@ -1,12 +1,9 @@
import { useTranslation } from 'react-i18next';
// import React from 'react';
import IconAdd from '../../../assets/icons/add.person.svg';
import IconBlock from '../../../assets/icons/block.svg';
import { useAppSelector } from '../../../app/store';
import { useUpdateContactStatusMutation } from '../../../app/services/user';
import { ContactAction } from '../../../types/user';
import ServerVersionChecker from '../../../common/component/ServerVersionChecker';
// import toast from 'react-hot-toast';
type Props = {
uid: number
@@ -15,36 +12,30 @@ type Props = {
const AddContactTip = (props: Props) => {
const { t } = useTranslation("chat");
const [updateContactStatus] = useUpdateContactStatusMutation();
const targetUser = useAppSelector(store => store.users.byId[props.uid]);
const { targetUser, enableContact } = useAppSelector(store => {
return { targetUser: store.users.byId[props.uid], enableContact: store.server.contact_verification_enable };
});
const handleContactStatus = (action: ContactAction) => {
updateContactStatus({ target_uid: props.uid, action });
};
// useEffect(() => {
// if(isSuccess){
// toast.success(t("tip"))
// }
// }, [isSuccess])
const itemClass = `cursor-pointer flex flex-col items-center gap-1 rounded-lg w-32 text-primary-400 bg-gray-50 dark:bg-gray-800 text-sm pt-3.5 pb-3`;
if (!targetUser) return null;
if (!targetUser || !enableContact) return null;
if (targetUser.status == "added") return null;
const blocked = targetUser.status == "blocked";
return (
<ServerVersionChecker version='0.3.7' empty={true}>
<div className="py-4 px-10 flex flex-col items-center gap-3 bg-slate-100 dark:bg-slate-600">
<h3 className='text-gray-700 dark:text-gray-300 text-sm font-semibold'>{blocked ? t("contact_block_tip") : t("contact_tip")}</h3>
<ul className='flex gap-4'>
{!blocked && <li className={itemClass} onClick={handleContactStatus.bind(null, "add")}>
<IconAdd className="fill-primary-400" />
<span>{t("add_contact")}</span>
</li>}
<li className={itemClass} onClick={blocked ? handleContactStatus.bind(null, "unblock") : handleContactStatus.bind(null, "block")}>
<IconBlock className="stroke-primary-400" />
<span>{blocked ? t("unblock") : t("block")}</span>
</li>
</ul>
</div>
</ServerVersionChecker>
<div className="py-4 px-10 flex flex-col items-center gap-3 bg-slate-100 dark:bg-slate-600">
<h3 className='text-gray-700 dark:text-gray-300 text-sm font-semibold'>{blocked ? t("contact_block_tip") : t("contact_tip")}</h3>
<ul className='flex gap-4'>
{!blocked && <li className={itemClass} onClick={handleContactStatus.bind(null, "add")}>
<IconAdd className="fill-primary-400" />
<span>{t("add_contact")}</span>
</li>}
<li className={itemClass} onClick={blocked ? handleContactStatus.bind(null, "unblock") : handleContactStatus.bind(null, "block")}>
<IconBlock className="stroke-primary-400" />
<span>{blocked ? t("unblock") : t("block")}</span>
</li>
</ul>
</div>
);
};
@@ -0,0 +1,39 @@
// import React from 'react'
import { useTranslation } from 'react-i18next';
import { useGetSystemCommonQuery, useUpdateSystemCommonMutation } from '../../../app/services/server';
import { useEffect } from 'react';
import { toast } from 'react-hot-toast';
import StyledRadio from "../../../common/component/styled/Radio";
import { useAppSelector } from '../../../app/store';
import SettingBlock from './SettingBlock';
// type Props = {}
const Index = () => {
const currStatus = useAppSelector(store => !!store.server.contact_verification_enable);
const { t } = useTranslation("setting", { keyPrefix: "overview.contact_verify" });
const { t: ct } = useTranslation();
const { refetch } = useGetSystemCommonQuery();
const [updateSetting, { isSuccess }] = useUpdateSystemCommonMutation();
useEffect(() => {
if (isSuccess) {
refetch();
toast.success(ct("tip.update"));
}
}, [isSuccess]);
const handleToggle = () => {
updateSetting({ contact_verification_enable: !currStatus });
};
// if (!loadSuccess) return null;
return (
<SettingBlock title={t("title")} desc={t('desc')} >
<StyledRadio
options={[t("enable"), t("disable")]}
values={["true", "false"]}
value={`${currStatus}`}
onChange={handleToggle}
/>
</SettingBlock>
);
};
export default Index;
+10 -3
View File
@@ -12,6 +12,7 @@ import ServerVersionChecker from "../../../common/component/ServerVersionChecker
import OnlineStatus from "./OnlineStatus";
import ChatLayout from "./ChatLayout";
import SettingBlock from "./SettingBlock";
import ContactVerification from "./ContactVerification";
export default function Overview() {
const { t } = useTranslation("setting");
@@ -40,6 +41,7 @@ export default function Overview() {
<h4 className="font-bold text-gray-700 dark:text-white">{t("overview.title_feat")}</h4>
<p className="text-gray-400 text-xs">{t("overview.title_feat_desc")}</p>
</div>
{/* 注册开放与否 */}
<SettingBlock title={t("overview.sign_up.title")} desc={t("overview.sign_up.desc")}>
<StyledRadio
options={[t("overview.sign_up.everyone"), t("overview.sign_up.invite")]}
@@ -50,6 +52,7 @@ export default function Overview() {
}}
/>
</SettingBlock>
{/* 访客模式 */}
<SettingBlock title={t("overview.guest_mode.title")} desc={t("overview.guest_mode.desc")}>
<StyledRadio
options={[t("overview.guest_mode.enable"), t("overview.guest_mode.disable")]}
@@ -60,15 +63,19 @@ export default function Overview() {
}}
/>
</SettingBlock>
{/* 是否显示在线提示 */}
<ServerVersionChecker version="0.3.4" empty={true}>
<OnlineStatus />
</ServerVersionChecker>
{/* 会话布局 */}
<ServerVersionChecker version="0.3.7" empty={true}>
<ChatLayout />
</ServerVersionChecker>
{/* <ServerVersionChecker version="0.3.7" empty={true}>
<FrontendURL />
</ServerVersionChecker> */}
{/* 联系人验证模式 */}
<ServerVersionChecker version="0.3.7" empty={true}>
<ContactVerification />
</ServerVersionChecker>
{/* 设置前端url */}
<ServerVersionChecker version="0.3.3" empty={true}>
<FrontendURL />
</ServerVersionChecker>