chore: polish UI
This commit is contained in:
@@ -94,9 +94,9 @@ const ChannelModal: FC<Props> = ({ personal = false, closeModal }) => {
|
||||
|
||||
return (
|
||||
<Modal>
|
||||
<div className="flex max-h-[402px] bg-white dark:bg-gray-800 drop-shadow rounded-lg">
|
||||
<div className="flex flex-col md:flex-row max-h-screen md:max-h-[402px] bg-white dark:bg-gray-800 drop-shadow rounded-lg">
|
||||
{!is_public && (
|
||||
<div className="w-[260px] shadow-[inset_-1px_0px_0px_rgba(0,_0,_0,_0.1)]">
|
||||
<div className="md:w-[260px] md:shadow-[inset_-1px_0px_0px_rgba(0,_0,_0,_0.1)]">
|
||||
<div className="sticky top-0 z-[99] rounded-tl-lg shadow-[0px_1px_0px_rgba(0,_0,_0,_0.1)] p-2 w-[calc(100%_-_1px)]">
|
||||
<input
|
||||
className="outline-none p-2 text-sm w-full bg-transparent dark:text-white"
|
||||
@@ -106,7 +106,7 @@ const ChannelModal: FC<Props> = ({ personal = false, closeModal }) => {
|
||||
/>
|
||||
</div>
|
||||
{users && (
|
||||
<ul className="flex flex-col overflow-y-scroll overflow-x-hidden h-[calc(100%_-_52px_-_10px)]">
|
||||
<ul className="flex flex-col overflow-y-scroll overflow-x-hidden max-h-80 md:h-[calc(100%_-_52px_-_10px)]">
|
||||
{users.map((u) => {
|
||||
const { uid } = u;
|
||||
const checked = members ? members.includes(uid) : false;
|
||||
@@ -134,19 +134,19 @@ const ChannelModal: FC<Props> = ({ personal = false, closeModal }) => {
|
||||
)}
|
||||
<div className={clsx(`w-80 md:min-w-[400px] flex flex-col items-center p-8 box-border`, !is_public && "w-[344px] justify-evenly")}>
|
||||
<h3 className="font-semibold text-xl text-gray-600 mb-4 dark:text-white">{t("create_channel")}</h3>
|
||||
<p className="text-gray-400 mb-12 text-sm font-normal">
|
||||
<p className="text-gray-400 mb-2 md:mb-12 text-sm font-normal">
|
||||
{!is_public
|
||||
? t("create_private_channel_desc")
|
||||
: t("create_channel_desc")}
|
||||
</p>
|
||||
<div className="w-full flex flex-col justify-start gap-2 mb-8">
|
||||
<div className="w-full flex flex-col justify-start gap-2 mb-2 md:mb-8">
|
||||
<span className="text-gray-400 text-sm font-normal">{t("channel_name")}</span>
|
||||
<div className="relative">
|
||||
<input className="text-gray-600 rounded p-2 pl-9 border border-solid border-gray-300 w-full bg-transparent" onChange={handleNameInput} value={name} placeholder="new channel" />
|
||||
<ChannelIcon personal={!is_public} className="absolute left-2 top-1/2 -translate-y-1/2" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-full flex items-center justify-between mb-12">
|
||||
<div className="w-full flex items-center justify-between mb-8 md:mb-12">
|
||||
<span className="text-gray-400 text-sm">{t("private_channel")}</span>
|
||||
<StyledToggle
|
||||
checked={!is_public}
|
||||
|
||||
@@ -80,13 +80,13 @@ const FileBox: FC<Props> = ({
|
||||
}) => {
|
||||
const fromUser = useAppSelector((store) => store.users.byId[from_uid]);
|
||||
const icon = getFileIcon(file_type, name, "icon w-9 h-12");
|
||||
if (!content || !fromUser || !name) return null;
|
||||
if (!content || !name) return null;
|
||||
const previewContent = renderPreview({ file_type, content, name });
|
||||
const withPreview = preview && previewContent;
|
||||
|
||||
return (
|
||||
<div
|
||||
className={clsx(`h-[66px] rounded-md border border-solid border-gray-300 dark:border-gray-500 bg-gray-100 dark:bg-gray-900`, flex ? "w-full" : "w-72 md:w-[370px]", withPreview && "relative overflow-hidden h-[281px]", file_type.startsWith("audio") && "h-[125px]")}
|
||||
className={clsx(`rounded-md border border-solid border-gray-300 dark:border-gray-500 bg-gray-100 dark:bg-gray-900`, flex ? "w-full" : "w-72 md:w-[370px]", withPreview ? "relative overflow-hidden h-[281px]" : "h-[66px] ", file_type.startsWith("audio") && "h-[125px]")}
|
||||
>
|
||||
<div className="w-full p-2 flex items-center justify-between gap-2">
|
||||
{icon}
|
||||
@@ -96,7 +96,7 @@ const FileBox: FC<Props> = ({
|
||||
<span className="size">{formatBytes(size)}</span>
|
||||
<span className="hidden md:block time">{fromNowTime(created_at)}</span>
|
||||
<span>
|
||||
by <strong className="font-bold">{fromUser.name}</strong>
|
||||
by <strong className="font-bold">{fromUser?.name || "Deleted User"}</strong>
|
||||
</span>
|
||||
</em>
|
||||
</div>
|
||||
|
||||
@@ -55,7 +55,7 @@ const Operations: FC<Props> = ({ context, id }) => {
|
||||
});
|
||||
const canDel = canDelete(mids);
|
||||
|
||||
const optClass = `p-2 bg-slate-100 rounded md:hover:bg-slate-300`;
|
||||
const optClass = `p-2 bg-slate-100 dark:bg-slate-800 rounded md:hover:bg-slate-300 dark:md:hover:bg-slate-900`;
|
||||
return (
|
||||
<>
|
||||
<div className="relative p-4 flex-center gap-8 shadow-md">
|
||||
|
||||
@@ -37,7 +37,7 @@ const SessionList: FC<Props> = ({ tempSession }) => {
|
||||
if (!mids || mids.length == 0) {
|
||||
return { key: `channel_${id}`, unreads: 0, id, type: "channel" };
|
||||
}
|
||||
const mid = [...mids].pop();
|
||||
const mid = [...mids].sort().pop();
|
||||
return { key: `channel_${id}`, id, mid, type: "channel" };
|
||||
});
|
||||
const uSessions = DMs.map((id) => {
|
||||
@@ -45,7 +45,7 @@ const SessionList: FC<Props> = ({ tempSession }) => {
|
||||
if (!mids || mids.length == 0) {
|
||||
return { key: `user_${id}`, unreads: 0, id, type: "user" };
|
||||
}
|
||||
const mid = [...mids].pop();
|
||||
const mid = [...mids].sort().pop();
|
||||
return { key: `user_${id}`, type: "user", id, mid };
|
||||
});
|
||||
const tmps = [...(cSessions as ChatSession[]), ...(uSessions as ChatSession[])].sort((a, b) => {
|
||||
|
||||
@@ -96,7 +96,7 @@ const MessageWrapper = ({ selectMode = false, context, id, mid, children, ...res
|
||||
dispatch(updateSelectMessages({ context, id, operation, data: mid }));
|
||||
};
|
||||
return (
|
||||
<div className={`flex items-start gap-2 relative w-full ${selectMode ? "hover:bg-slate-100" : ""}`} {...rest}>
|
||||
<div className={`flex items-start gap-2 relative w-full ${selectMode ? "hover:bg-slate-100 dark:hover:bg-slate-900" : ""}`} {...rest}>
|
||||
{selectMode && <Checkbox className="!mt-4 !ml-2" checked={selected} />}
|
||||
{children}
|
||||
{selectMode && (
|
||||
|
||||
@@ -122,7 +122,7 @@ export default function LoginPage() {
|
||||
const hasDivider =
|
||||
enableMagicLink || googleLogin || enableMetamaskLogin || oidc.length > 0 || enableGithubLogin;
|
||||
|
||||
if (loadingSMTPStatus) return "Loading...";
|
||||
if (loadingSMTPStatus) return null;
|
||||
return (
|
||||
<div className="flex-center h-screen dark:bg-gray-700">
|
||||
<div className="py-8 px-10 shadow-md rounded-xl">
|
||||
|
||||
@@ -38,11 +38,12 @@ let msnry: Masonry | null;
|
||||
function ResourceManagement({ fileMessages }) {
|
||||
const listContainerRef = useRef<HTMLDivElement>();
|
||||
const [filter, setFilter] = useState({});
|
||||
const { message, view, channelMessage } = useAppSelector((store) => {
|
||||
const { message, view, channelMessage, userData } = useAppSelector((store) => {
|
||||
return {
|
||||
message: store.message,
|
||||
channelMessage: store.channelMessage,
|
||||
view: store.ui.fileListView
|
||||
view: store.ui.fileListView,
|
||||
userData: store.users.byId
|
||||
};
|
||||
});
|
||||
|
||||
@@ -96,6 +97,8 @@ function ResourceManagement({ fileMessages }) {
|
||||
const data = message[id];
|
||||
if (!data) return null;
|
||||
const isSelected = checkFilter(data, filter, channelMessage);
|
||||
// 过滤掉不存在的用户
|
||||
// const fromUser = userData[data.from_uid];
|
||||
if (!isSelected) return null;
|
||||
const { mid, content, created_at, from_uid, properties } = data;
|
||||
const { name, content_type, size } = properties ?? {};
|
||||
|
||||
@@ -72,7 +72,7 @@ const WebhookEdit = ({ uid }: Props) => {
|
||||
evt.preventDefault();
|
||||
handleEdit();
|
||||
}}>
|
||||
<input readOnly={!editable} required autoFocus type="url" name='webhook' defaultValue={url} className={clsx("text-sm text-gray-500 dark:text-gray-100 px-2 py-1", editable ? "border border-solid border-gray-200 bg-gray-50" : "bg-transparent")} />
|
||||
<input readOnly={!editable} required autoFocus type="url" name='webhook' defaultValue={url} className={clsx("text-sm text-gray-500 dark:text-gray-100 dark:bg-slate-900 px-2 py-1", editable ? "ring-1 ring-gray-500 bg-gray-50" : "bg-transparent")} />
|
||||
</form>
|
||||
<button type='button' disabled={isUpdating} onClick={handleEdit}>
|
||||
{isUpdating ? <Orbit size={16} /> : editable ?
|
||||
|
||||
@@ -85,7 +85,7 @@ export default function BotConfig() {
|
||||
<tbody>
|
||||
{bots.map(bot => {
|
||||
const { uid, name, avatar } = bot;
|
||||
return <tr key={uid} className="bg-white dark:bg-gray-800 border-b dark:border-b-gray-500 transition duration-300 ease-in-out md:hover:bg-gray-100">
|
||||
return <tr key={uid} className="bg-white dark:bg-gray-800 border-b dark:border-b-gray-500 transition duration-300 ease-in-out md:hover:bg-gray-100 dark:md:hover:bg-transparent">
|
||||
<td className="px-4 py-2">
|
||||
<AvatarUploader uid={uid} url={avatar} uploadImage={updateAvatar} name={name} size={56} />
|
||||
</td>
|
||||
|
||||
@@ -29,7 +29,7 @@ export default function Widget() {
|
||||
{t('code')}:
|
||||
</label>
|
||||
<SyntaxHighlighter id="code" language="html" style={vscDarkPlus} className="rounded">
|
||||
{`<!-- ${t('code_comment')} -->\n<script \n data-host-id="1" \n data-theme-color="#1fe1f9" \n data-close-width="48" \n data-close-height="48" \n data-open-width="380" \n data-open-height="680" \n src="${location.origin}/widget.js" \n async \n/>`}
|
||||
{`<!-- ${t('code_comment')} -->\n<script \n data-host-id="1" \n data-theme-color="#1fe1f9" \n data-close-width="48" \n data-close-height="48" \n data-open-width="380" \n data-open-height="680" \n src="${location.origin}/widget.js" \n async \n></script>`}
|
||||
</SyntaxHighlighter>
|
||||
<div className="text-gray-500 dark:text-white text-sm mt-5 mb-2">
|
||||
{t('config')}:
|
||||
@@ -55,7 +55,7 @@ export default function Widget() {
|
||||
}, {
|
||||
paramKey: "close-width",
|
||||
paramDefault: `48(px)`,
|
||||
remarks: t("param_open_width")
|
||||
remarks: t("param_close_width")
|
||||
}, {
|
||||
paramKey: "close-height",
|
||||
paramDefault: `48(px)`,
|
||||
|
||||
@@ -29,7 +29,7 @@ function UsersPage() {
|
||||
return (
|
||||
<div className={clsx("flex h-screen md:h-full md:pt-2 md:pb-2.5 md:pr-12")}>
|
||||
<div className={clsx("md:rounded-l-2xl bg-white dark:bg-gray-800 relative flex flex-col w-full md:w-auto md:min-w-[268px] shadow-[inset_-1px_0px_0px_rgba(0,_0,_0,_0.1)]",
|
||||
isUserDetail && "hidden"
|
||||
isUserDetail && "hidden md:flex"
|
||||
)}>
|
||||
<Search input={input} updateInput={updateInput} />
|
||||
<div className="px-2 pt-3 pb-20 md:py-3 overflow-scroll">
|
||||
|
||||
Reference in New Issue
Block a user