diff --git a/external/lang b/external/lang index 3931bf87e94264d92556a2f3ee96c6051be75b02..9f72b064aad85293f332c3f7ce3f4fe5965def37 160000 --- a/external/lang +++ b/external/lang @@ -1 +1 @@ -Subproject commit 3931bf87e94264d92556a2f3ee96c6051be75b02 +Subproject commit 9f72b064aad85293f332c3f7ce3f4fe5965def37 diff --git a/package.json b/package.json index 767f3009c4b96577122b10950ec6c8cc449bc5b6..d531110fdad30d5fb3fc2132b8f200b1eee967c9 100644 --- a/package.json +++ b/package.json @@ -94,7 +94,7 @@ "react-router-dom": "^5.2.0", "react-scroll": "^1.8.2", "redux": "^4.1.0", - "revolt.js": "4.3.3-alpha.14", + "revolt.js": "4.3.3-alpha.15", "rimraf": "^3.0.2", "sass": "^1.35.1", "shade-blend-color": "^1.0.0", diff --git a/src/components/common/messaging/Message.tsx b/src/components/common/messaging/Message.tsx index 8e87ae282fdb2a77be755f4ae27786409f8ff2c3..c55d251e31c07377b9465f2ee5e0035505407924 100644 --- a/src/components/common/messaging/Message.tsx +++ b/src/components/common/messaging/Message.tsx @@ -1,6 +1,6 @@ import { attachContextMenu } from "preact-context-menu"; import { memo } from "preact/compat"; -import { useContext } from "preact/hooks"; +import { useContext, useState } from "preact/hooks"; import { QueuedMessage } from "../../../redux/reducers/queue"; @@ -64,6 +64,9 @@ function Message({ const openProfile = () => openScreen({ id: "profile", user_id: message.author }); + // ! FIXME: animate on hover + const [animate, setAnimate] = useState(false); + return ( <div id={message._id}> {message.replies?.map((message_id, index) => ( @@ -88,7 +91,9 @@ function Message({ queued, }) : undefined - }> + } + onMouseEnter={() => setAnimate(true)} + onMouseLeave={() => setAnimate(false)}> <MessageInfo> {head ? ( <UserIcon @@ -96,6 +101,7 @@ function Message({ size={36} onContextMenu={userContext} onClick={openProfile} + animate={animate} /> ) : ( <MessageDetail message={message} position="left" /> diff --git a/src/context/Locale.tsx b/src/context/Locale.tsx index a0d1836fe432784d35d75c68d475f3dc8a729c3e..5366027a528b4365c205e591974a7487a0467492 100644 --- a/src/context/Locale.tsx +++ b/src/context/Locale.tsx @@ -150,7 +150,10 @@ function Locale({ children, locale }: Props) { const dayjs = obj.dayjs; const defaults = dayjs.defaults; - const twelvehour = defaults?.twelvehour === "yes" || true; + const twelvehour = defaults?.twelvehour + ? defaults.twelvehour === "yes" + : false; + const separator: string = defaults?.date_separator ?? "/"; const date: "traditional" | "simplified" | "ISO8601" = defaults?.date_format ?? "traditional"; diff --git a/src/context/intermediate/popovers/UserProfile.tsx b/src/context/intermediate/popovers/UserProfile.tsx index bc07e4d247ca45d936e6e993ffeefdc6c5db68a7..ff77647ca9e5b21b6236ace1e66ea6e654fae111 100644 --- a/src/context/intermediate/popovers/UserProfile.tsx +++ b/src/context/intermediate/popovers/UserProfile.tsx @@ -141,7 +141,7 @@ export function UserProfile({ user_id, onClose, dummy, dummyProfile }: Props) { `linear-gradient( rgba(0, 0, 0, 0.7), rgba(0, 0, 0, 0.7) ), url('${backgroundURL}')`, }}> <div className={styles.profile}> - <UserIcon size={80} target={user} status /> + <UserIcon size={80} target={user} status animate /> <div className={styles.details}> <Localizer> <span diff --git a/src/pages/settings/Settings.module.scss b/src/pages/settings/Settings.module.scss index 6a8b310854969c4502aab8638c3c26a0a15f0752..6fa0666a1e79b263871d337e98ae2f655390ae0c 100644 --- a/src/pages/settings/Settings.module.scss +++ b/src/pages/settings/Settings.module.scss @@ -1,24 +1,41 @@ @keyframes open { - 0% {transform: scale(1.2);}; - 100% {transform: scale(1);}; + 0% { + transform: scale(1.2); + } + 100% { + transform: scale(1); + } } @keyframes close { - 0% {transform: scale(1); opacity: 1;}; - 100% {transform: scale(1.2); opacity: 0;}; + 0% { + transform: scale(1); + opacity: 1; + } + 100% { + transform: scale(1.2); + opacity: 0; + } } @keyframes opacity { - 0% {opacity: 0;}; - 20% {opacity: .5;} - 50% {opacity: 1;} + 0% { + opacity: 0; + } + 20% { + opacity: 0.5; + } + 50% { + opacity: 1; + } } .settings[data-mobile="true"] { flex-direction: column; background: var(--primary-header); - .sidebar, .content { + .sidebar, + .content { background: var(--primary-background); } @@ -36,7 +53,6 @@ .version { place-items: center; - } } @@ -52,8 +68,7 @@ width: 100%; height: 100%; position: fixed; - animation: open .18s ease-out, - opacity .18s; + animation: open 0.18s ease-out, opacity 0.18s; } .settings { @@ -166,7 +181,7 @@ flex-shrink: 0; padding: 60px 8px; color: var(--tertiary-background); - + &:after { content: "ESC"; margin-top: 4px; @@ -177,8 +192,8 @@ position: relative; color: var(--foreground); width: 40px; - opacity: .5; - font-size: .75em; + opacity: 0.5; + font-size: 0.75em; } .closeButton { @@ -190,7 +205,7 @@ width: 40px; border: 3px solid var(--tertiary-background); cursor: pointer; - + svg { color: var(--secondary-foreground); } @@ -208,6 +223,10 @@ display: inline; } } + + section { + margin-bottom: 1em; + } } .loader { diff --git a/src/pages/settings/server/Panes.module.scss b/src/pages/settings/server/Panes.module.scss index 93ca2cc379d65ad244ac2ef67e9a97c697ffb9ff..deb0d421f9753084c0123ada154e035b51153ae2 100644 --- a/src/pages/settings/server/Panes.module.scss +++ b/src/pages/settings/server/Panes.module.scss @@ -39,7 +39,8 @@ flex-direction: row; background: var(--secondary-background); - code, span { + code, + span { flex: 1; } @@ -69,7 +70,7 @@ color: var(--secondary-foreground); font-weight: 700; } - + .member { gap: 8px; padding: 10px; @@ -95,10 +96,6 @@ flex-grow: 1; padding: 0 8px; overflow-y: scroll; - - section { - margin-bottom: 1em; - } } .title { @@ -107,7 +104,8 @@ margin-bottom: 1em; align-items: center; - h1, h2 { + h1, + h2 { margin: 0; min-width: 0; flex-grow: 1; @@ -126,4 +124,4 @@ display: flex; padding: 8px 0; } -} \ No newline at end of file +} diff --git a/src/pages/settings/server/Roles.tsx b/src/pages/settings/server/Roles.tsx index 489adbf89c5c505603834c5a0d58eb62e155a738..f765e82986c0efcc4fb5fbcaf202ea21d69fd7b9 100644 --- a/src/pages/settings/server/Roles.tsx +++ b/src/pages/settings/server/Roles.tsx @@ -15,6 +15,7 @@ import { AppContext } from "../../../context/revoltjs/RevoltClient"; import Button from "../../../components/ui/Button"; import Checkbox from "../../../components/ui/Checkbox"; +import ColourSwatches from "../../../components/ui/ColourSwatches"; import IconButton from "../../../components/ui/IconButton"; import InputBox from "../../../components/ui/InputBox"; import Overline from "../../../components/ui/Overline"; @@ -40,21 +41,46 @@ export function Roles({ server }: Props) { return null; } - const v = (id: string) => - I32ToU32( + function getPermissions(id: string) { + return I32ToU32( id === "default" ? server.default_permissions : roles[id].permissions, ); - const [perm, setPerm] = useState(v(role)); - useEffect(() => setPerm(v(role)), [role, roles[role]?.permissions]); - - const modified = !isEqual(perm, v(role)); - const save = () => - client.servers.setPermissions(server._id, role, { - server: perm[0], - channel: perm[1], - }); + } + + const { name: roleName, colour: roleColour } = roles[role] ?? {}; + + const [perm, setPerm] = useState(getPermissions(role)); + const [name, setName] = useState(roleName); + const [colour, setColour] = useState(roleColour); + + useEffect( + () => setPerm(getPermissions(role)), + [role, roles[role]?.permissions], + ); + + useEffect(() => setName(roleName), [role, roleName]); + useEffect(() => setColour(roleColour), [role, roleColour]); + + const modified = + !isEqual(perm, getPermissions(role)) || + !isEqual(name, roleName) || + !isEqual(colour, roleColour); + + const save = () => { + if (!isEqual(perm, getPermissions(role))) { + client.servers.setPermissions(server._id, role, { + server: perm[0], + channel: perm[1], + }); + } + + if (!isEqual(name, roleName) || !isEqual(colour, roleColour)) { + client.servers.editRole(server._id, role, { name, colour }); + } + }; + const deleteRole = () => { setRole("default"); client.servers.deleteRole(server._id, role); @@ -92,7 +118,8 @@ export function Roles({ server }: Props) { return ( <ButtonItem active={role === id} - onClick={() => setRole(id)}> + onClick={() => setRole(id)} + style={{ color: roles[id].colour }}> {roles[id].name} </ButtonItem> ); @@ -111,6 +138,31 @@ export function Roles({ server }: Props) { Save </Button> </div> + {role !== "default" && ( + <> + <section> + <Overline type="subtle">Role Name</Overline> + <p> + <InputBox + value={name} + onChange={(e) => + setName(e.currentTarget.value) + } + contrast + /> + </p> + </section> + <section> + <Overline type="subtle">Role Colour</Overline> + <p> + <ColourSwatches + value={colour ?? "gray"} + onChange={(value) => setColour(value)} + /> + </p> + </section> + </> + )} <section> <Overline type="subtle"> <Text id="app.settings.permissions.server" /> diff --git a/yarn.lock b/yarn.lock index 2926089170bbff9809f4b00e834995a5ef1565c6..05ad5dbff5f577992d6c4692901305caea14aeb9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3563,10 +3563,10 @@ reusify@^1.0.4: resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== -revolt.js@4.3.3-alpha.14: - version "4.3.3-alpha.14" - resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.3.3-alpha.14.tgz#f4912ee25725de6e43ba1d4fd8ab84c711678271" - integrity sha512-4p3DhEu+GUKZxczCPXR2JM04fzGlFfZdwHYjgkgU48NgPXgzxQrSv4x0FjpyIIv3xNpuO59z35mYRMLxAnBXsQ== +revolt.js@4.3.3-alpha.15: + version "4.3.3-alpha.15" + resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.3.3-alpha.15.tgz#e511ad500a20f658b15b7bad0fdb9e2a5465d1b1" + integrity sha512-24hIQEO+FIRIAQXITBH2qVvWH6LA1MeJW2/3lj6cqBgJz7lnb3ZNIXZBu5sHbUEJpIDtJiHcOEeaeh3sE2RwxA== dependencies: "@insertish/mutable" "1.1.0" axios "^0.19.2"