diff --git a/external/lang b/external/lang index 332cc2d7..f3d13c09 160000 --- a/external/lang +++ b/external/lang @@ -1 +1 @@ -Subproject commit 332cc2d7125b9cfb26ce211a9cb0fbf29301946c +Subproject commit f3d13c09b6fa2f28f027ce32643caffadbb63cf1 diff --git a/package.json b/package.json index bce943b8..a1a8deb8 100644 --- a/package.json +++ b/package.json @@ -73,7 +73,7 @@ "react-scroll": "^1.8.2", "react-tippy": "^1.4.0", "redux": "^4.1.0", - "revolt.js": "4.3.1-alpha.0", + "revolt.js": "4.3.2", "rimraf": "^3.0.2", "sass": "^1.35.1", "shade-blend-color": "^1.0.0", diff --git a/src/components/common/ChannelIcon.tsx b/src/components/common/ChannelIcon.tsx index a7934624..fb4d1a50 100644 --- a/src/components/common/ChannelIcon.tsx +++ b/src/components/common/ChannelIcon.tsx @@ -1,10 +1,10 @@ import { useContext } from "preact/hooks"; -import { Hash } from "@styled-icons/feather"; import { Channels } from "revolt.js/dist/api/objects"; +import { Hash, Volume2 } from "@styled-icons/feather"; import { ImageIconBase, IconBaseProps } from "./IconBase"; import { AppContext } from "../../context/revoltjs/RevoltClient"; -interface Props extends IconBaseProps { +interface Props extends IconBaseProps { isServerChannel?: boolean; } @@ -15,13 +15,19 @@ export default function ChannelIcon(props: Props & Omit - ) + if (target?.channel_type === 'VoiceChannel') { + return ( + + ) + } else { + return ( + + ) + } } } diff --git a/src/components/common/messaging/Message.tsx b/src/components/common/messaging/Message.tsx index 362c0875..28ee957c 100644 --- a/src/components/common/messaging/Message.tsx +++ b/src/components/common/messaging/Message.tsx @@ -22,13 +22,14 @@ interface Props { head?: boolean } -export default function Message({ attachContext, message, contrast, content: replacement, head, queued }: Props) { +export default function Message({ attachContext, message, contrast, content: replacement, head: preferHead, queued }: Props) { // TODO: Can improve re-renders here by providing a list // TODO: of dependencies. We only need to update on u/avatar. const user = useUser(message.author); const client = useContext(AppContext); const content = message.content as string; + const head = (message.replies && message.replies.length > 0) || preferHead; return ( void } & ( - { type: "create_group" | "create_server" | "set_custom_status" | "add_friend" } | - { type: "create_channel", server: string } + { type: "create_group" | "create_server" | "set_custom_status" | "add_friend" } ) export function SpecialInputModal(props: SpecialProps) { @@ -110,24 +109,6 @@ export function SpecialInputModal(props: SpecialProps) { }} />; } - case "create_channel": { - return } - field={} - callback={async name => { - const channel = await client.servers.createChannel( - props.server, - { - name, - nonce: ulid() - } - ); - - history.push(`/server/${props.server}/channel/${channel._id}`); - }} - />; - } case "set_custom_status": { return void } & ( { type: "delete_message", target: Channels.Message } | { type: "create_invite", target: Channels.TextChannel | Channels.GroupChannel } | { type: "kick_member", target: Servers.Server, user: string } | - { type: "ban_member", target: Servers.Server, user: string } + { type: "ban_member", target: Servers.Server, user: string } | + { type: "create_channel", target: Servers.Server } ) export function SpecialPromptModal(props: SpecialProps) { @@ -263,6 +267,59 @@ export function SpecialPromptModal(props: SpecialProps) { /> ) } + case 'create_channel': { + const [ name, setName ] = useState(''); + const [ type, setType ] = useState<'Text' | 'Voice'>('Text'); + const history = useHistory(); + + return ( + } + actions={[ + { + confirmation: true, + contrast: true, + text: , + onClick: async () => { + setProcessing(true); + + try { + const channel = await client.servers.createChannel( + props.target._id, + { + type, + name, + nonce: ulid() + } + ); + + history.push(`/server/${props.target._id}/channel/${channel._id}`); + onClose(); + } catch (err) { + setError(takeError(err)); + setProcessing(false); + } + } + }, + { text: , onClick: onClose } + ]} + content={<> + + setType('Text')}> + + setType('Voice')}> + + + setName(e.currentTarget.value)} /> + } + disabled={processing} + error={error} + /> + ) + } default: return null; } } diff --git a/src/lib/ContextMenus.tsx b/src/lib/ContextMenus.tsx index 73e54033..d5c84676 100644 --- a/src/lib/ContextMenus.tsx +++ b/src/lib/ContextMenus.tsx @@ -60,7 +60,7 @@ type Action = | { action: "set_presence"; presence: Users.Presence } | { action: "set_status" } | { action: "clear_status" } - | { action: "create_channel"; server: string } + | { action: "create_channel"; target: Servers.Server } | { action: "create_invite"; target: Channels.GroupChannel | Channels.TextChannel } | { action: "leave_group"; target: Channels.GroupChannel } | { action: "delete_channel"; target: Channels.TextChannel } @@ -92,7 +92,8 @@ function ContextMenus(props: WithDispatcher) { break; case "mark_as_read": { - if (data.channel.channel_type === 'SavedMessages') return; + if (data.channel.channel_type === 'SavedMessages' || + data.channel.channel_type === 'VoiceChannel') return; let message = data.channel.channel_type === 'TextChannel' ? data.channel.last_message : data.channel.last_message._id; props.dispatcher({ @@ -280,14 +281,13 @@ function ContextMenus(props: WithDispatcher) { case "delete_channel": case "delete_server": case "delete_message": + case "create_channel": // @ts-expect-error case "create_invite": openScreen({ id: "special_prompt", type: data.action, target: data.target }); break; case "ban_member": case "kick_member": openScreen({ id: "special_prompt", type: data.action, target: data.target, user: data.user }); break; - case "create_channel": openScreen({ id: "special_input", type: "create_channel", server: data.server }); break; - case "open_channel_settings": history.push(`/channel/${data.id}/settings`); break; case "open_server_channel_settings": history.push(`/server/${data.server}/channel/${data.id}/settings`); break; case "open_server_settings": history.push(`/server/${data.id}/settings`); break; @@ -341,9 +341,12 @@ function ContextMenus(props: WithDispatcher) { } if (server_list) { + let server = useServer(server_list, forceUpdate); let permissions = useServerPermission(server_list, forceUpdate); - if (permissions & ServerPermission.ManageChannels) generateAction({ action: 'create_channel', server: server_list }); - if (permissions & ServerPermission.ManageServer) generateAction({ action: 'open_server_settings', id: server_list }); + if (server) { + if (permissions & ServerPermission.ManageChannels) generateAction({ action: 'create_channel', target: server }); + if (permissions & ServerPermission.ManageServer) generateAction({ action: 'open_server_settings', id: server_list }); + } return elements; } diff --git a/src/pages/channels/Channel.tsx b/src/pages/channels/Channel.tsx index 8d32b3b3..70a7d02b 100644 --- a/src/pages/channels/Channel.tsx +++ b/src/pages/channels/Channel.tsx @@ -10,6 +10,7 @@ import { useChannel, useForceUpdate } from "../../context/revoltjs/hooks"; import MemberSidebar from "../../components/navigation/right/MemberSidebar"; import JumpToBottom from "../../components/common/messaging/bars/JumpToBottom"; import TypingIndicator from "../../components/common/messaging/bars/TypingIndicator"; +import { Channel } from "revolt.js"; const ChannelMain = styled.div` flex-grow: 1; @@ -31,22 +32,36 @@ export function Channel({ id }: { id: string }) { const channel = useChannel(id, ctx); if (!channel) return null; + + if (channel.channel_type === 'VoiceChannel') { + return ; + } else { + return ; + } +} + +function TextChannel({ channel }: { channel: Channel }) { const [ showMembers, setMembers ] = useState(true); - return ( - <> - setMembers(!showMembers)} /> - - - - - - - - { !isTouchscreenDevice && showMembers && } - - - ) + let id = channel._id; + return <> + setMembers(!showMembers)} /> + + + + + + + + { !isTouchscreenDevice && showMembers && } + + ; +} + +function VoiceChannel({ channel }: { channel: Channel }) { + return <> + + ; } export default function() { diff --git a/src/pages/settings/channel/Overview.tsx b/src/pages/settings/channel/Overview.tsx index 30c36b9f..60e8cce2 100644 --- a/src/pages/settings/channel/Overview.tsx +++ b/src/pages/settings/channel/Overview.tsx @@ -9,7 +9,7 @@ import { AppContext } from "../../../context/revoltjs/RevoltClient"; import { FileUploader } from "../../../context/revoltjs/FileUploads"; interface Props { - channel: Channels.GroupChannel | Channels.TextChannel; + channel: Channels.GroupChannel | Channels.TextChannel | Channels.VoiceChannel; } export function Overview({ channel }: Props) { diff --git a/yarn.lock b/yarn.lock index 18f56c48..2ec69299 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3344,10 +3344,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.1-alpha.0: - version "4.3.1-alpha.0" - resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.3.1-alpha.0.tgz#21abb0706852468a0b7991a80d81093f547d25f3" - integrity sha512-YwDdDgioVYeBYkgZtgtXM37//96WmT18XVPJ7cBJzDQ3GWUKKPrw4VFjmi9FSh0ksfgfkSIrA7/hqmztZWbnVw== +revolt.js@4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/revolt.js/-/revolt.js-4.3.2.tgz#2e613ff1d918d77266e9c777e226bfbddd5a9b87" + integrity sha512-JyD3fRaory3Rhy/sAWcvHjLb/CluJRZap2Di2ZFFf9uiRJBgLNlClS/3RkBLAcQqx4KVx7Ua3WbKq1/dU6x7dQ== dependencies: "@insertish/mutable" "1.1.0" axios "^0.19.2"