chore: updates
This commit is contained in:
+1
-1
@@ -185,5 +185,5 @@ export const getInviteLinkTimesList = () => [
|
||||
value: 100
|
||||
}
|
||||
];
|
||||
|
||||
export const KEY_ADMIN_SEE_CHANNEL_MEMBERS = `only_admin_can_see_channel_members`;
|
||||
export default BASE_URL;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import QR from "qrcode.react";
|
||||
import { QRCodeSVG } from "qrcode.react";
|
||||
|
||||
import { useAppSelector } from "@/app/store";
|
||||
import { shallowEqual } from "react-redux";
|
||||
@@ -13,14 +13,14 @@ const QRCode = ({ link, size = 512, level = "L" }: Props) => {
|
||||
const logo = useAppSelector((store) => store.server.logo, shallowEqual);
|
||||
return (
|
||||
<div className="p-2 bg-white dark:bg-slate-200 rounded">
|
||||
<QR
|
||||
renderAs="svg"
|
||||
<QRCodeSVG
|
||||
value={link}
|
||||
className="rounded border border-solid border-gray-200 dark:border-none !w-full !h-full"
|
||||
size={size}
|
||||
bgColor={"#fff"}
|
||||
fgColor={"#000"}
|
||||
level={level}
|
||||
marginSize={2}
|
||||
// includeMargin={true}
|
||||
imageSettings={{
|
||||
src: logo,
|
||||
|
||||
@@ -19,6 +19,8 @@ import VoiceChat from "../VoiceChat";
|
||||
import Dashboard from "../VoiceChat/Dashboard";
|
||||
import Members from "./Members";
|
||||
import PinList from "./PinList";
|
||||
import { getJSONField } from "@/utils";
|
||||
import { KEY_ADMIN_SEE_CHANNEL_MEMBERS } from "@/app/config";
|
||||
|
||||
type Props = {
|
||||
cid?: number;
|
||||
@@ -29,13 +31,17 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
|
||||
const { pathname } = useLocation();
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const serverExtSetting = useAppSelector(
|
||||
(store) => store.server.ext_setting ?? "{}",
|
||||
shallowEqual
|
||||
);
|
||||
const loginUser = useAppSelector((store) => store.authData.user, shallowEqual);
|
||||
const visibleAside = useAppSelector((store) => store.footprint.channelAsides[cid], shallowEqual);
|
||||
const userIds = useAppSelector((store) => store.users.ids, shallowEqual);
|
||||
const data = useAppSelector((store) => store.channels.byId[cid], shallowEqual);
|
||||
useEffect(() => {
|
||||
if (!data) {
|
||||
// channel不存在了 回首页
|
||||
// channel 不存在了 回首页
|
||||
navigate("/chat");
|
||||
}
|
||||
}, [data]);
|
||||
@@ -61,6 +67,9 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
|
||||
const addVisible = loginUser?.is_admin || owner == loginUser?.uid;
|
||||
const pinCount = data?.pinned_messages?.length || 0;
|
||||
const toolClass = `relative cursor-pointer hidden md:block`;
|
||||
const onlyAdminCanSeeMembers =
|
||||
getJSONField(serverExtSetting, KEY_ADMIN_SEE_CHANNEL_MEMBERS) ?? false;
|
||||
const canViewMembers = loginUser?.is_admin ? true : onlyAdminCanSeeMembers;
|
||||
return (
|
||||
<Layout
|
||||
to={cid}
|
||||
@@ -102,11 +111,13 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
|
||||
</li>
|
||||
</Tippy>
|
||||
</Tooltip>
|
||||
<li className={`${toolClass}`} onClick={toggleMembersVisible}>
|
||||
<Tooltip tip={t("channel_members")} placement="left">
|
||||
<IconPeople className={visibleAside == "members" ? "fill-gray-600" : ""} />
|
||||
</Tooltip>
|
||||
</li>
|
||||
{canViewMembers && (
|
||||
<li className={`${toolClass}`} onClick={toggleMembersVisible}>
|
||||
<Tooltip tip={t("channel_members")} placement="left">
|
||||
<IconPeople className={visibleAside == "members" ? "fill-gray-600" : ""} />
|
||||
</Tooltip>
|
||||
</li>
|
||||
)}
|
||||
</ul>
|
||||
}
|
||||
header={
|
||||
@@ -125,13 +136,15 @@ function ChannelChat({ cid = 0, dropFiles = [] }: Props) {
|
||||
</header>
|
||||
}
|
||||
users={
|
||||
<Members
|
||||
uids={memberIds}
|
||||
addVisible={addVisible}
|
||||
cid={cid}
|
||||
ownerId={owner}
|
||||
membersVisible={visibleAside == "members"}
|
||||
/>
|
||||
canViewMembers ? (
|
||||
<Members
|
||||
uids={memberIds}
|
||||
addVisible={addVisible}
|
||||
cid={cid}
|
||||
ownerId={owner}
|
||||
membersVisible={visibleAside == "members"}
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
voice={<Dashboard visible={visibleAside == "voice"} id={cid} context="channel" />}
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import { useAppSelector } from "@/app/store";
|
||||
import SettingBlock from "@/components/SettingBlock";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import StyledRadio from "@/components/styled/Radio";
|
||||
import { useGetSystemCommonQuery, useUpdateSystemCommonMutation } from "@/app/services/server";
|
||||
import { useEffect } from "react";
|
||||
import toast from "react-hot-toast";
|
||||
import { shallowEqual } from "react-redux";
|
||||
import ServerVersionChecker from "@/components/ServerVersionChecker";
|
||||
import { getJSONField, upsertJSON } from "@/utils";
|
||||
import { KEY_ADMIN_SEE_CHANNEL_MEMBERS } from "@/app/config";
|
||||
|
||||
type Props = {};
|
||||
|
||||
const OnlyAdminCanSeeChannelMembers = ({}: Props) => {
|
||||
const { t } = useTranslation("setting");
|
||||
const { t: ct } = useTranslation();
|
||||
const { refetch } = useGetSystemCommonQuery();
|
||||
const serverExtSetting = useAppSelector(
|
||||
(store) => store.server.ext_setting ?? "{}",
|
||||
shallowEqual
|
||||
);
|
||||
const [updateSetting, { isSuccess }] = useUpdateSystemCommonMutation();
|
||||
useEffect(() => {
|
||||
if (isSuccess) {
|
||||
refetch();
|
||||
toast.success(ct("tip.update"));
|
||||
}
|
||||
}, [isSuccess]);
|
||||
const handleChange = (newVal: boolean) => {
|
||||
const json = upsertJSON(serverExtSetting, { only_admin_can_see_channel_members: newVal });
|
||||
updateSetting({ ext_setting: json });
|
||||
};
|
||||
const onlyAdminSeeChannelMembers =
|
||||
getJSONField(serverExtSetting, KEY_ADMIN_SEE_CHANNEL_MEMBERS) ?? false;
|
||||
return (
|
||||
<ServerVersionChecker empty version="0.3.50">
|
||||
<SettingBlock
|
||||
title={t("overview.admin_see_group_members.title")}
|
||||
desc={t("overview.admin_see_group_members.desc")}
|
||||
>
|
||||
<StyledRadio
|
||||
options={[
|
||||
t("overview.admin_see_group_members.enable"),
|
||||
t("overview.admin_see_group_members.disable")
|
||||
]}
|
||||
values={["true", "false"]}
|
||||
value={`${onlyAdminSeeChannelMembers}`}
|
||||
onChange={(v) => {
|
||||
handleChange(v == "true");
|
||||
}}
|
||||
/>
|
||||
</SettingBlock>
|
||||
</ServerVersionChecker>
|
||||
);
|
||||
};
|
||||
|
||||
export default OnlyAdminCanSeeChannelMembers;
|
||||
@@ -16,6 +16,7 @@ import MessageSound from "./MessageSound";
|
||||
import Server from "./Server";
|
||||
import { shallowEqual } from "react-redux";
|
||||
import OnlyAdminCreateGroup from "./OnlyAdminCreateGroup";
|
||||
import OnlyAdminCanSeeChannelMembers from "./OnlyAdminSeeChannelMembers";
|
||||
|
||||
export default function Overview() {
|
||||
const { t } = useTranslation("setting");
|
||||
@@ -57,6 +58,7 @@ export default function Overview() {
|
||||
{/* 只有 admin 能创建群组 */}
|
||||
|
||||
<OnlyAdminCreateGroup />
|
||||
<OnlyAdminCanSeeChannelMembers />
|
||||
{/* 访客模式 */}
|
||||
<SettingBlock title={t("overview.guest_mode.title")} desc={t("overview.guest_mode.desc")}>
|
||||
<StyledRadio
|
||||
|
||||
@@ -507,6 +507,23 @@ export const playMessageSound = async () => {
|
||||
console.warn("play join sound failed!", error);
|
||||
}
|
||||
};
|
||||
export const getJSONField = (json: string | null, field: string) => {
|
||||
try {
|
||||
const obj = json ? JSON.parse(json) : {};
|
||||
return obj[field];
|
||||
} catch (error) {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
export const upsertJSON = (json: string | null, obj: object) => {
|
||||
try {
|
||||
const jsonObj = json ? JSON.parse(json) : {};
|
||||
const result = Object.assign({}, jsonObj, obj);
|
||||
return JSON.stringify(result);
|
||||
} catch (error) {
|
||||
return JSON.stringify(obj);
|
||||
}
|
||||
};
|
||||
export const isInIframe = () => window.location !== window.parent.location;
|
||||
export const encodeBase64 = (str = "") => btoa(unescape(encodeURIComponent(str)));
|
||||
export const shouldPreviewImage = (type: string) => {
|
||||
|
||||
Reference in New Issue
Block a user