Skip to content

Commit

Permalink
банан яблоко сожрал
Browse files Browse the repository at this point in the history
  • Loading branch information
officialdakari committed Sep 16, 2024
1 parent d3f8b0b commit be23798
Show file tree
Hide file tree
Showing 11 changed files with 259 additions and 225 deletions.
2 changes: 2 additions & 0 deletions src/app/atoms/button/Button.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import Icon from '@mdi/react';
const Button = React.forwardRef(({
id, className, variant, iconSrc,
type, onClick, children, disabled,
onMouseDown
}, ref) => {
const iconClass = (iconSrc === null) ? '' : `btn-${variant}--icon`;
return (
Expand All @@ -18,6 +19,7 @@ const Button = React.forwardRef(({
id={id === '' ? undefined : id}
className={`${className ? `${className} ` : ''}btn-${variant} ${iconClass} noselect`}
onMouseUp={(e) => blurOnBubbling(e, `.btn-${variant}`)}
onMouseDown={onMouseDown}
onClick={onClick}
// eslint-disable-next-line react/button-has-type
type={type}
Expand Down
143 changes: 72 additions & 71 deletions src/app/atoms/context-menu/ContextMenu.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,106 +10,107 @@ import Button from '../button/Button';
import ScrollView from '../scroll/ScrollView';

function ContextMenu({
content, placement, maxWidth, render, afterToggle,
content, placement, maxWidth, render, afterToggle,
}) {
const [isVisible, setVisibility] = useState(false);
const showMenu = () => setVisibility(true);
const hideMenu = () => setVisibility(false);
const [isVisible, setVisibility] = useState(false);
const showMenu = () => setVisibility(true);
const hideMenu = () => setVisibility(false);

useEffect(() => {
if (afterToggle !== null) afterToggle(isVisible);
}, [isVisible]);
useEffect(() => {
if (afterToggle !== null) afterToggle(isVisible);
}, [isVisible]);

return (
<Tippy
animation="scale-extreme"
className="context-menu"
visible={isVisible}
onClickOutside={hideMenu}
content={<ScrollView invisible>{typeof content === 'function' ? content(hideMenu) : content}</ScrollView>}
placement={placement}
interactive
arrow={false}
maxWidth={maxWidth}
duration={200}
>
{render(isVisible ? hideMenu : showMenu)}
</Tippy>
);
return (
<Tippy
animation="scale-extreme"
className="context-menu"
visible={isVisible}
onClickOutside={hideMenu}
content={<ScrollView invisible>{typeof content === 'function' ? content(hideMenu) : content}</ScrollView>}
placement={placement}
interactive
arrow={false}
maxWidth={maxWidth}
duration={200}
>
{render(isVisible ? hideMenu : showMenu)}
</Tippy>
);
}

ContextMenu.defaultProps = {
maxWidth: 'unset',
placement: 'right',
afterToggle: null,
maxWidth: 'unset',
placement: 'right',
afterToggle: null,
};

ContextMenu.propTypes = {
content: PropTypes.oneOfType([
PropTypes.node,
PropTypes.func,
]).isRequired,
placement: PropTypes.oneOf(['top', 'right', 'bottom', 'left']),
maxWidth: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
render: PropTypes.func.isRequired,
afterToggle: PropTypes.func,
content: PropTypes.oneOfType([
PropTypes.node,
PropTypes.func,
]).isRequired,
placement: PropTypes.oneOf(['top', 'right', 'bottom', 'left']),
maxWidth: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
]),
render: PropTypes.func.isRequired,
afterToggle: PropTypes.func,
};

function MenuHeader({ children }) {
return (
<div className="context-menu__header">
<Text variant="b3">{ children }</Text>
</div>
);
return (
<div className="context-menu__header">
<Text variant="b3">{children}</Text>
</div>
);
}

MenuHeader.propTypes = {
children: PropTypes.node.isRequired,
children: PropTypes.node.isRequired,
};

function MenuItem({
variant, iconSrc, type,
onClick, children, disabled,
variant, iconSrc, type,
onClick, children, disabled,
}) {
return (
<div className="context-menu__item">
<Button
variant={variant}
iconSrc={iconSrc}
type={type}
onClick={onClick}
disabled={disabled}
>
{ children }
</Button>
</div>
);
return (
<div className="context-menu__item">
<Button
variant={variant}
iconSrc={iconSrc}
type={type}
onClick={onClick}
disabled={disabled}
onMouseDown={(evt) => { evt.stopPropagation(); evt.preventDefault(); }}
>
{children}
</Button>
</div>
);
}

MenuItem.defaultProps = {
variant: 'surface',
iconSrc: null,
type: 'button',
disabled: false,
onClick: null,
variant: 'surface',
iconSrc: null,
type: 'button',
disabled: false,
onClick: null,
};

MenuItem.propTypes = {
variant: PropTypes.oneOf(['surface', 'positive', 'caution', 'danger']),
iconSrc: PropTypes.string,
type: PropTypes.oneOf(['button', 'submit']),
onClick: PropTypes.func,
children: PropTypes.node.isRequired,
disabled: PropTypes.bool,
variant: PropTypes.oneOf(['surface', 'positive', 'caution', 'danger']),
iconSrc: PropTypes.string,
type: PropTypes.oneOf(['button', 'submit']),
onClick: PropTypes.func,
children: PropTypes.node.isRequired,
disabled: PropTypes.bool,
};

function MenuBorder() {
return <div style={{ borderBottom: '1px solid var(--bg-surface-border)' }}> </div>;
return <div style={{ borderBottom: '1px solid var(--bg-surface-border)' }}> </div>;
}

export {
ContextMenu as default, MenuHeader, MenuItem, MenuBorder,
ContextMenu as default, MenuHeader, MenuItem, MenuBorder,
};
2 changes: 1 addition & 1 deletion src/app/features/room/RoomInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -790,7 +790,7 @@ export const RoomInput = forwardRef<HTMLDivElement, RoomInputProps>(
setEmojiBoardTab(showStickerButton ? EmojiBoardTab.Sticker : EmojiBoardTab.Emoji)
}
}}
//onMouseDown={dontHideKeyboard}
onMouseDown={dontHideKeyboard}
variant="SurfaceVariant"
size="300"
radii="300"
Expand Down
22 changes: 18 additions & 4 deletions src/app/pages/client/ClientNonUIFeatures.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ import { Permissions } from '../../state/widgetPermissions';
import { randomNumberBetween } from '../../utils/common';
import { removeNotifications, roomIdToHash } from '../../utils/notifications';
import { markAsRead } from '../../../client/action/notifications';
import cons from '../../../client/state/cons';
import { getText } from '../../../lang';

function FaviconUpdater() {
const roomToUnread = useAtomValue(roomToUnreadAtom);
Expand Down Expand Up @@ -301,10 +303,10 @@ export function ClientNonUIFeatures({ children }: ClientNonUIFeaturesProps) {

useEffect(() => {
const clickHandler = async (ev: any) => {
const href = ev.target.getAttribute('data-mention-href') ?? ev.target.getAttribute('href');
if (typeof href !== 'string') return;
const url = parse(href as string);
if (ev.target.tagName?.toLowerCase() === 'a' || ev.target.tagName?.toLowerCase() === 'span') {
const href = ev.target.getAttribute('data-mention-href') ?? ev.target.getAttribute('href');
if (!href) return;
const url = parse(href as string);
console.log(url);
if (url.hostname === 'matrix.to' && typeof url.hash === 'string' && url.hash.length > 3) {
ev.preventDefault();
Expand All @@ -329,14 +331,23 @@ export function ClientNonUIFeatures({ children }: ClientNonUIFeaturesProps) {
} else if (type == '#') {
openJoinAlias(id);
}
return;
}
}
if (ev.target.tagName?.toLowerCase() === 'a') {
if (!cons.trustedDomains.includes(url.host!) && !cons.trustedDomains.includes(url.hostname!)) {
ev.preventDefault();
if (await confirmDialog(getText('go_link.title'), `${getText('go_link.desc')}\n\n${href}`, getText('go_link.yes'), 'danger')) {
window.open(href, '_blank');
}
}
}
};
addEventListener('click', clickHandler);
return () => {
removeEventListener('click', clickHandler);
};
}, []);
}, [roomId]);

// todo refactor that shit
// TODO means I will never do that
Expand Down Expand Up @@ -437,6 +448,7 @@ export function ClientNonUIFeatures({ children }: ClientNonUIFeaturesProps) {
if (!event) return respond({ error: { message: 'No state event' } });
respond(event.getContent());
} else if (data.action === 'set_bot_options') {
//@ts-ignore
mx?.sendStateEvent(data.room_id, 'm.room.bot.options', data.content)
.then(() => {
respond({ success: true });
Expand Down Expand Up @@ -469,6 +481,7 @@ export function ClientNonUIFeatures({ children }: ClientNonUIFeaturesProps) {
join_rule: room.getJoinRule()
});
} else if (data.action === 'set_plumbing_state') {
//@ts-ignore
mx?.sendStateEvent(data.room_id, 'm.room.plumbing', { status: data.status })
.then(() => {
respond({ success: true });
Expand Down Expand Up @@ -511,6 +524,7 @@ export function ClientNonUIFeatures({ children }: ClientNonUIFeaturesProps) {
respond(widgetsEvents.map(s => s.getEffectiveEvent()));
} else if (data.action === 'set_widget') {
if (data.url) {
//@ts-ignore
mx?.sendStateEvent(data.room_id, 'im.vector.modular.widgets', {
widget_id: data.widget_id,
type: data.type,
Expand Down
17 changes: 11 additions & 6 deletions src/app/plugins/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ const LinkRule: InlineMDRule = {
},
};

const ESCAPE_REG_1 = /\\(\*|`|_)/;
const ESCAPE_REG_1 = /\\(\*|`|_|>|&gt;)/;
const EscapeRule: InlineMDRule = {
match: (text) => text.match(ESCAPE_REG_1),
html: (parse, match) => {
Expand Down Expand Up @@ -283,15 +283,15 @@ const CodeBlockRule: BlockMDRule = {
};

const BLOCKQUOTE_MD_1 = '>';
const QUOTE_LINE_PREFIX = /^> */;
const QUOTE_LINE_PREFIX = /^(&gt;|>)((&amp;|&)(#[a-f0-9]{6}))? */;
const COLOR_PREFIX = /^(&gt;|>)(&amp;|&)(#[a-f0-9]{6})/;
const BLOCKQUOTE_TRAILING_NEWLINE = /\n$/;
const BLOCKQUOTE_REG_1 = /(^>.*\n?)+/m;
const BLOCKQUOTE_REG_1 = /((^&gt;|^>)((&amp;|&)(#[a-f0-9]+))?.*\n?)+/m;
const BlockQuoteRule: BlockMDRule = {
match: (text) => text.match(BLOCKQUOTE_REG_1),
html: (match, parseInline) => {
const [blockquoteText] = match;
console.log(`blockquote`, match);

console.log(`!!! blockquote`, match);
const lines = blockquoteText
.replace(BLOCKQUOTE_TRAILING_NEWLINE, '')
.split('\n')
Expand All @@ -301,7 +301,12 @@ const BlockQuoteRule: BlockMDRule = {
return `${line}<br/>`;
})
.join('');
return `<blockquote data-md="${BLOCKQUOTE_MD_1}">${lines}</blockquote>`;
const arr = blockquoteText.match(COLOR_PREFIX);
var color;
if (arr) {
if (typeof arr[3] === 'string') color = arr[3];
}
return `<blockquote data-md="${BLOCKQUOTE_MD_1}" ${color ? `data-blockquote-color="${color}"` : ''}>${lines}</blockquote>`;
},
};

Expand Down
3 changes: 2 additions & 1 deletion src/app/plugins/react-custom-html-parser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export const getReactCustomHtmlParser = (
replace: (domNode) => {
if (domNode instanceof Element && 'name' in domNode) {
const { name, attribs, children, parent } = domNode;
if (name === 'blockquote') console.debug(`!!! ${name}`, domNode);
const props = attributesToProps(attribs);

if (name === 'h1') {
Expand Down Expand Up @@ -163,7 +164,7 @@ export const getReactCustomHtmlParser = (

if (name === 'blockquote') {
return (
<Text {...props} size="Inherit" as="blockquote" className={css.BlockQuote} style={props['data-mx-color'] ? { borderColor: props['data-mx-color'] } : undefined}>
<Text {...props} size="Inherit" as="blockquote" className={css.BlockQuote} style={props['data-blockquote-color'] ? { borderColor: props['data-blockquote-color'] } : undefined}>
{domToReact(children, opts)}
</Text>
);
Expand Down
2 changes: 1 addition & 1 deletion src/app/styles/CustomHtml.css.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const Spoiler = recipe({
DefaultReset,
{
padding: `0 ${config.space.S100}`,
backgroundColor: color.SurfaceVariant.ContainerActive,
backgroundColor: color.SurfaceVariant.ContainerLine,
borderRadius: config.radii.R300,
selectors: {
'&[aria-pressed=true]': {
Expand Down
Loading

0 comments on commit be23798

Please sign in to comment.