chore: polish UI

This commit is contained in:
Tristan Yang
2023-02-23 22:20:15 +08:00
parent d10df4bee5
commit 8a5259a9fd
11 changed files with 24 additions and 21 deletions
+6 -6
View File
@@ -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}
+3 -3
View File
@@ -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>
+1 -1
View File
@@ -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">
+2 -2
View File
@@ -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) => {
+1 -1
View File
@@ -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 && (
+1 -1
View File
@@ -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">
+5 -2
View File
@@ -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 ?? {};
+1 -1
View File
@@ -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 ?
+1 -1
View File
@@ -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>
+2 -2
View File
@@ -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)`,
+1 -1
View File
@@ -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">