Add server creation button.

Add profile links / app links back.
Add quoting / mentioning back.
This commit is contained in:
Paul 2021-06-22 11:56:37 +01:00
parent 8fe1ce3450
commit 454ee7fd6e
10 changed files with 88 additions and 83 deletions

View file

@ -6,20 +6,20 @@ import IconButton from "../../ui/IconButton";
import { Send } from '@styled-icons/feather';
import Axios, { CancelTokenSource } from "axios";
import { useTranslation } from "../../../lib/i18n";
import { useCallback, useContext, useState } from "preact/hooks";
import { connectState } from "../../../redux/connector";
import { WithDispatcher } from "../../../redux/reducers";
import { takeError } from "../../../context/revoltjs/util";
import TextAreaAutoSize from "../../../lib/TextAreaAutoSize";
import { AppContext } from "../../../context/revoltjs/RevoltClient";
import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
import { internalEmit, internalSubscribe } from "../../../lib/eventEmitter";
import { useCallback, useContext, useEffect, useState } from "preact/hooks";
import { useIntermediate } from "../../../context/intermediate/Intermediate";
import { FileUploader, grabFiles, uploadFile } from "../../../context/revoltjs/FileUploads";
import { SingletonMessageRenderer, SMOOTH_SCROLL_ON_RECEIVE } from "../../../lib/renderer/Singleton";
import FilePreview from './bars/FilePreview';
import { debounce } from "../../../lib/debounce";
import { internalEmit } from "../../../lib/eventEmitter";
type Props = WithDispatcher & {
channel: Channel;
@ -71,6 +71,26 @@ function MessageBox({ channel, draft, dispatcher }: Props) {
}
}
useEffect(() => {
function append(content: string, action: 'quote' | 'mention') {
const text =
action === "quote"
? `${content
.split("\n")
.map(x => `> ${x}`)
.join("\n")}\n\n`
: `${content} `;
if (!draft || draft.length === 0) {
setMessage(text);
} else {
setMessage(`${draft}\n${text}`);
}
}
return internalSubscribe("MessageBox", "append", append);
}, [ draft ]);
async function send() {
if (uploadState.type === 'uploading' || uploadState.type === 'sending') return;
@ -241,7 +261,7 @@ function MessageBox({ channel, draft, dispatcher }: Props) {
autoFocus
hideBorder
maxRows={5}
padding={15}
padding={14}
id="message"
value={draft ?? ''}
onKeyDown={e => {

View file

@ -4,6 +4,7 @@ import { generateEmoji } from "./Emoji";
import { useContext } from "preact/hooks";
import { MarkdownProps } from "./Markdown";
import styles from "./Markdown.module.scss";
import { internalEmit } from "../../lib/eventEmitter";
import { AppContext } from "../../context/revoltjs/RevoltClient";
import Prism from "prismjs";
@ -70,9 +71,9 @@ if (typeof window !== "undefined") {
const pathname = url.pathname;
if (pathname.startsWith("/@")) {
//InternalEventEmitter.emit("openProfile", pathname.substr(2));
internalEmit("Intermediate", "openProfile", pathname.substr(2));
} else {
//InternalEventEmitter.emit("navigate", pathname);
internalEmit("Intermediate", "navigate", pathname.substr(2));
}
};
}

View file

@ -7,19 +7,19 @@ export default styled.div`
user-select: none;
flex-direction: row;
align-items: stretch;
${ isTouchscreenDevice && css`
padding-bottom: 50px;
` }
`;
export const GenericSidebarBase = styled.div`
export const GenericSidebarBase = styled.div<{ padding?: boolean }>`
height: 100%;
width: 240px;
display: flex;
flex-shrink: 0;
flex-direction: column;
background: var(--secondary-background);
${ props => props.padding && isTouchscreenDevice && css`
padding-bottom: 50px;
` }
`;
export const GenericSidebarList = styled.div`

View file

@ -49,7 +49,7 @@ function HomeSidebar(props: Props) {
channelsArr.sort((b, a) => a.timestamp.localeCompare(b.timestamp));
return (
<GenericSidebarBase>
<GenericSidebarBase padding>
<UserHeader user={client.user!} />
<ConnectionStatus />
<GenericSidebarList>

View file

@ -1,14 +1,18 @@
import IconButton from "../../ui/IconButton";
import LineDivider from "../../ui/LineDivider";
import { mapChannelWithUnread } from "./common";
import styled, { css } from "styled-components";
import ServerIcon from "../../common/ServerIcon";
import { Children } from "../../../types/Preact";
import { PlusCircle } from "@styled-icons/feather";
import PaintCounter from "../../../lib/PaintCounter";
import { attachContextMenu } from 'preact-context-menu';
import { connectState } from "../../../redux/connector";
import { Unreads } from "../../../redux/reducers/unreads";
import { Channel, Servers } from "revolt.js/dist/api/objects";
import { Link, useLocation, useParams } from "react-router-dom";
import { isTouchscreenDevice } from "../../../lib/isTouchscreenDevice";
import { useIntermediate } from "../../../context/intermediate/Intermediate";
import { useChannels, useForceUpdate, useServers } from "../../../context/revoltjs/hooks";
import logoSVG from '../../../assets/logo.svg';
@ -49,6 +53,10 @@ const ServersBase = styled.div`
height: 100%;
display: flex;
flex-direction: column;
${ isTouchscreenDevice && css`
padding-bottom: 50px;
` }
`;
const ServerList = styled.div`
@ -128,7 +136,7 @@ export function ServerListSidebar({ unreads }: Props) {
const { server: server_id } = useParams<{ server?: string }>();
const server = servers.find(x => x!._id == server_id);
// const { openScreen } = useContext(IntermediateContext);
const { openScreen } = useIntermediate();
let homeUnread: 'mention' | 'unread' | undefined;
let alertCount = 0;
@ -166,43 +174,12 @@ export function ServerListSidebar({ unreads }: Props) {
</Link>
)
}
<PaintCounter small />
</ServerList>
</ServersBase>
// ! FIXME: add overlay back
/*<div className={styles.servers}>
<div className={styles.list}>
<Link to={`/`}>
<div className={styles.entry}
data-active={typeof server === 'undefined' && !path.startsWith('/invite')}>
<Icon size={36} unread={homeUnread} alertCount={alertCount}>
<div className={styles.logo} />
</Icon>
</div>
</Link>
<LineDivider className={styles.divider} />
{
servers.map(entry =>
<Link to={`/server/${entry!._id}`}>
<div className={styles.entry}
data-active={entry!._id === server?._id}
onContextMenu={attachContextMenu('Menu', { server: entry!._id })}>
<Icon size={36} unread={entry.unread}>
<ServerIcon id={entry!._id} size={32} />
</Icon>
</div>
</Link>
)
}
</div>
<div className={styles.overlay}>
<div className={styles.actions}>
<IconButton onClick={() => openScreen({ id: 'special_input', type: 'create_server' })}>
<PlusCircle size={36} />
</IconButton>
</div>
</div>
</div> */
<PaintCounter small />
</ServerList>
</ServersBase>
)
}

View file

@ -9,16 +9,16 @@ import Theme from "./Theme";
export default function Context({ children }: { children: Children }) {
return (
<BrowserRouter>
<State>
<Locale>
<Intermediate>
<BrowserRouter>
<ClientContext>
<Theme>{children}</Theme>
</ClientContext>
</BrowserRouter>
</Intermediate>
</Locale>
</State>
</BrowserRouter>
);
}

View file

@ -1,9 +1,11 @@
import { Attachment, Channels, EmbedImage, Servers } from "revolt.js/dist/api/objects";
import { useContext, useEffect, useMemo, useState } from "preact/hooks";
import { internalSubscribe } from "../../lib/eventEmitter";
import { Action } from "../../components/ui/Modal";
import { useHistory } from "react-router-dom";
import { Children } from "../../types/Preact";
import { createContext } from "preact";
import { Prompt } from "react-router";
import Modals from './Modals';
export type Screen =
@ -92,17 +94,15 @@ export default function Intermediate(props: Props) {
}, []);
useEffect(() => {
// const openProfile = (user_id: string) =>
// openScreen({ id: "profile", user_id });
// const navigate = (path: string) => history.push(path);
const openProfile = (user_id: string) => openScreen({ id: "profile", user_id });
const navigate = (path: string) => history.push(path);
// InternalEventEmitter.addListener("openProfile", openProfile);
// InternalEventEmitter.addListener("navigate", navigate);
const subs = [
internalSubscribe("Intermediate", "open_profile", openProfile),
internalSubscribe("Intermediate", "navigate", navigate)
]
return () => {
// InternalEventEmitter.removeListener("openProfile", openProfile);
// InternalEventEmitter.removeListener("navigate", navigate);
};
return () => subs.map(unsub => unsub());
}, []);
return (
@ -116,15 +116,19 @@ export default function Intermediate(props: Props) {
screen.id
} /** By specifying a key, we reset state whenever switching screen. */
/>
{/*<Prompt
when={screen.id !== 'none'}
message={() => {
<Prompt
when={[ 'modify_account', 'special_prompt', 'special_input', 'image_viewer', 'profile', 'channel_info', 'user_picker' ].includes(screen.id)}
message={(_, action) => {
if (action === 'POP') {
openScreen({ id: 'none' });
setTimeout(() => history.push(history.location), 0);
return false;
}
return true;
}}
/>*/}
/>
</IntermediateActionsContext.Provider>
</IntermediateContext.Provider>
);

View file

@ -138,12 +138,12 @@ function ContextMenus(props: WithDispatcher) {
case "mention":
{
// edit draft
/*InternalEventEmitter.emit(
"append_messagebox",
internalEmit(
"MessageBox",
"append",
`<@${data.user}>`,
"mention"
);*/
);
}
break;
@ -152,12 +152,12 @@ function ContextMenus(props: WithDispatcher) {
break;
case "quote_message":
{
// edit draft
/*InternalEventEmitter.emit(
"append_messagebox",
internalEmit(
"MessageBox",
"append",
data.content,
"quote"
);*/
);
}
break;
@ -190,10 +190,10 @@ function ContextMenus(props: WithDispatcher) {
case "copy_file_link":
{
const { _id, filename } = data.attachment;
const { filename } = data.attachment;
writeClipboard(
// ! FIXME: do from r.js
client.generateFileURL(data.attachment) + '/${encodeURI(filename)}',
client.generateFileURL(data.attachment) + `/${encodeURI(filename)}`,
);
}
break;

View file

@ -15,4 +15,7 @@ export function internalEmit(ns: string, event: string, ...args: any[]) {
/// Event List
// - MessageRenderer/edit_last
// - MessageRenderer/edit_message
// - MessageBox/focus
// - Intermediate/open_profile
// - Intermediate/navigate
// - MessageBox/append
// - TextArea/focus

View file

@ -14,7 +14,7 @@
100% {transform: scale(1.2); opacity: 0;};
}
[data-touchscreen-device="true"] .settings {
.settings[data-mobile="true"] {
flex-direction: column;
background: var(--primary-header);
@ -45,7 +45,7 @@
}
}
:global(.app):not([data-touchscreen-device="true"]) .settings {
.settings:not([data-mobile="true"]) {
top: 0;
left: 0;
z-index: 10;