Skip to content

Commit

Permalink
Temp
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastianStehle committed Sep 28, 2023
1 parent 2b21267 commit c80dd68
Show file tree
Hide file tree
Showing 24 changed files with 170 additions and 84 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"reselect": "4.1.5",
"tslib": "2.3.1",
"y-webrtc": "^10.2.5",
"yjs-redux": "^0.6.0"
"yjs-redux": "^0.7.0"
},
"scripts": {
"start": "node --max_old_space_size=6096 node_modules/webpack/bin/webpack.js serve --config config/webpack.config.js --port 3002 --hot --server-type https --server-options-pfx dev/squidex-dev.pfx --server-options-passphrase password",
Expand Down
6 changes: 4 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,11 @@ export const App = () => {
] = usePrinter();

React.useEffect(() => {
const token = routeTokenSnapshot.current;
const token = routeTokenSnapshot.current as string;

if (token && token.length > 0) {
if (token?.indexOf('c:') === 0) {
dispatch(newDiagram(false, token.substring(2)));
} else if (token?.length > 0) {
dispatch(loadDiagramFromServer({ tokenToRead: token, navigate: false }));
} else {
dispatch(newDiagram(false));
Expand Down
2 changes: 1 addition & 1 deletion src/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export * from './react/ColorPicker';
export * from './react/Clipboard';
export * from './react/Grid';
export * from './react/hooks';
export * from './react/MarkerButton';
export * from './react/marker';
export * from './react/Shortcut';
export * from './react/Title';
export * from './react/UserReport';
Expand Down
18 changes: 8 additions & 10 deletions src/core/react/MarkerButton.tsx → src/core/react/marker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@
* Copyright (c) Sebastian Stehle. All rights reserved.
*/

import { SmileOutlined } from '@ant-design/icons';
import markerSDK, { MarkerSdk } from '@marker.io/browser';
import { Button } from 'antd';
import * as React from 'react';

export const MarkerButton = () => {
export function useMarker() {
const [widget, setWidget] = React.useState<MarkerSdk>();

React.useEffect(() => {
Expand All @@ -26,10 +24,10 @@ export const MarkerButton = () => {

loadMarker();
}, []);
return (
<Button className='menu-item' onClick={() => widget?.capture('advanced')}>
<SmileOutlined />
</Button>
);
};

const open = React.useCallback(() => {
widget?.capture('advanced');
}, [widget]);

return { open };
}
16 changes: 12 additions & 4 deletions src/core/utils/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ export function isModKey(key: KeyboardEvent | MouseEvent) {
const escapeTestNoEncode = /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/;
const escapeReplaceNoEncode = new RegExp(escapeTestNoEncode.source, 'g');
const escapeReplacements = {
'&' : '&amp;',
'<' : '&lt;',
'>' : '&gt;',
'"' : '&quot;',
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
'\'': '&#39;',
};

Expand All @@ -40,6 +40,14 @@ export function escapeHTML(html: string) {
return html;
}

export async function copyTextToClipboard(text: string) {
if ('clipboard' in navigator) {
return await navigator.clipboard.writeText(text);
} else {
return document.execCommand('copy', true, text);
}
}

export module Keys {
const ALT = 18;
const COMMA = 188;
Expand Down
12 changes: 12 additions & 0 deletions src/style/_common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,18 @@ ul {
padding-bottom: 10px;
}

.share {
padding: 10px;

.ant-input-group {
display: flex;
line-height: 1rem;
flex-flow: row;
flex-wrap: nowrap;
margin-top: 5px;
}
}

//
// Sidebars
//
Expand Down
4 changes: 4 additions & 0 deletions src/texts/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ export const texts = {
backgroundColor: 'Background Color',
bringForwards: 'Bring Forwards',
bringToFront: 'Bring to Front',
bug: 'Report a Bug',
colors: 'Colors',
copied: 'Link copied to clipboard',
copy: 'Copy',
copyTooltip: 'Copy Items',
custom: 'Custom',
Expand All @@ -37,6 +39,7 @@ export const texts = {
findShape: 'Find Shape',
fontSize: 'Font Size',
foregroundColor: 'Foreground Color',
github: 'Github & Source Code',
group: 'Group',
groupTooltip: 'Group Items',
height: 'Height',
Expand Down Expand Up @@ -83,6 +86,7 @@ export const texts = {
savingDiagramDoneUrl: (fullUrl: string) => `Saving diagram completed under ${fullUrl}.`,
sendBackwards: 'Send Backwards',
sendToBack: 'Send to Back',
shareText: 'Share the following link to work together on this wireframe',
shapes: 'Shapes',
strokeColor: 'Stroke Color',
strokeThickness: 'Stroke Thickness',
Expand Down
58 changes: 49 additions & 9 deletions src/wireframes/collaboration/components/Presence.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Avatar } from 'antd';
import { CopyOutlined, ShareAltOutlined } from '@ant-design/icons';
import { Avatar, Button, Dropdown, Input, message } from 'antd';
import * as React from 'react';
import { usePresence } from '../hooks';
import { copyTextToClipboard } from '@app/core';
import { texts } from '@app/texts';
import { useStore } from '@app/wireframes/model';
import { usePresence } from './../hooks';

export const Presence = () => {
const editor = useStore(x => x.editor);
const editorId = editor.id;
const presence = usePresence();

const sortedUsers = React.useMemo(() => {
Expand All @@ -17,12 +23,46 @@ export const Presence = () => {
}, [presence]);

return (
<Avatar.Group>
{sortedUsers.map(user =>
<Avatar key={user.id} style={{ backgroundColor: user.color }}>
{user.initial}
</Avatar>,
)}
</Avatar.Group>
<>
{sortedUsers.length > 1 &&
<Avatar.Group>
{sortedUsers.map(user =>
<Avatar key={user.id} style={{ backgroundColor: user.color }}>
{user.initial}
</Avatar>,
)}
</Avatar.Group>
}

<Dropdown overlay={<ShareMenu id={editorId} />}>
<Button className='menu-item' size='large'>
<ShareAltOutlined />
</Button>
</Dropdown>
</>
);
};

export const ShareMenu = ({ id }: { id: string }) => {
const link = `${window.location.protocol}//${window.location.host}/c:${id}`;

const doCopy = () => {
copyTextToClipboard(link);

message.open({ content: texts.common.copied, key: 'clipboard', type: 'info' });
};

return (
<div className='share ant-menu ant-menu-root'>
{texts.common.shareText}

<Input.Group compact>
<Input value={link} />

<Button onClick={doCopy}>
<CopyOutlined />
</Button>
</Input.Group>
</div>
);
};
9 changes: 5 additions & 4 deletions src/wireframes/collaboration/components/Provider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import { CollaborationContext, CollaborationState } from './../hooks';

export const CollaborationProvider = (props: { children: React.ReactNode }) => {
const [state, setState] = React.useState<CollaborationState>({});
const editorId = useStore(x => x.editor.id);
const editorBinder = useYjsReduxBinder();
const binder = useYjsReduxBinder();
const editor = useStore(x => x.editor);
const editorId = editor.id;

useAsyncEffect(async cancellation => {
const clientDoc = new Y.Doc();
Expand Down Expand Up @@ -47,7 +48,7 @@ export const CollaborationProvider = (props: { children: React.ReactNode }) => {
return undefined;
}

const unbind = editorBinder.connectSlice(clientDoc, 'editor',
const unbind = binder.connectSlice(clientDoc, 'editor',
root => {
setState(state => ({
...state,
Expand All @@ -66,7 +67,7 @@ export const CollaborationProvider = (props: { children: React.ReactNode }) => {

unbind();
};
}, [editorId, editorBinder]);
}, [editorId, binder]);

return (
<CollaborationContext.Provider value={state}>
Expand Down
4 changes: 2 additions & 2 deletions src/wireframes/components/CustomDragLayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

import * as React from 'react';
import { useDragLayer, XYCoord } from 'react-dnd';
import { ShapePlugin } from '../interface';
import { getViewBox, ShapeRenderer } from '../shapes/ShapeRenderer';
import { ShapePlugin } from '@app/wireframes/interface';
import { getViewBox, ShapeRenderer } from '@app/wireframes/shapes/ShapeRenderer';
import './CustomDragLayer.scss';

export const CustomDragLayer = () => {
Expand Down
3 changes: 1 addition & 2 deletions src/wireframes/components/EditorView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ import { NativeTypes } from 'react-dnd-html5-backend';
import { findDOMNode } from 'react-dom';
import { useDispatch } from 'react-redux';
import { loadImagesToClipboardItems, sizeInPx, useClipboard, useEventCallback } from '@app/core';
import { addShape, changeItemsAppearance, Diagram, getDiagram, getDiagramId, getEditor, getMasterDiagram, getSelectedItems, RendererService, selectItems, Transform, transformItems, useStore } from '@app/wireframes/model';
import { addShape, changeItemsAppearance, Diagram, DiagramRef, getDiagram, getDiagramId, getEditor, getMasterDiagram, getSelectedItems, ItemsRef, RendererService, selectItems, Transform, transformItems, useStore } from '@app/wireframes/model';
import { Editor } from '@app/wireframes/renderer/Editor';
import { DiagramRef, ItemsRef } from '../model/actions/utils';
import { ShapeSource } from './../interface';
import { ContextMenu } from './context-menu/ContextMenu';
import './EditorView.scss';
Expand Down
12 changes: 6 additions & 6 deletions src/wireframes/components/actions/Components.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import * as React from 'react';
import { isMac, Shortcut, Types } from '@app/core';
import { UIAction } from './shared';

type ActionDisplayMode = 'Icon' | 'IconLabel' | 'Label';
type ActionDisplayMode = 'IconOnly' | 'IconLabel' | 'Label';

type ActionProps = {
// The action to show.
Expand Down Expand Up @@ -46,7 +46,7 @@ export const ActionMenuButton = React.memo((props: ActionProps & ButtonProps) =>
<>
<Tooltip mouseEnterDelay={1} title={title}>
<Button {...other} type={type} className={!type ? 'menu-item' : undefined} size='large' disabled={disabled} onClick={onAction}>
<ButtonContent icon={icon} label={label} displayMode={displayMode || 'Icon'} />
<ButtonContent icon={icon} label={label} displayMode={displayMode || 'IconOnly'} />
</Button>
</Tooltip>

Expand Down Expand Up @@ -83,7 +83,7 @@ export const ActionDropdownButton = React.memo((props: ActionProps & DropdownBut
</Tooltip>,
React.cloneElement(rightButton as React.ReactElement<any, string>),
]}>
<ButtonContent icon={icon} label={label} displayMode={displayMode || 'Icon'} />
<ButtonContent icon={icon} label={label} displayMode={displayMode || 'IconOnly'} />
</Dropdown.Button>

{shortcut &&
Expand Down Expand Up @@ -114,7 +114,7 @@ export const ActionButton = React.memo((props: ActionProps & ButtonProps) => {
<>
<Tooltip mouseEnterDelay={1} title={title}>
<Button {...other} disabled={disabled} onClick={onAction}>
<ButtonContent icon={icon} label={label} displayMode={displayMode || 'Icon'} />
<ButtonContent icon={icon} label={label} displayMode={displayMode || 'IconOnly'} />
</Button>
</Tooltip>
</>
Expand All @@ -138,7 +138,7 @@ export const ActionMenuItem = React.memo((props: ActionProps & MenuItemProps) =>

return (
<Menu.Item {...other} key={label} className='force-color' disabled={disabled} onClick={onAction}
icon={(actualDisplayMode === 'Icon' || actualDisplayMode === 'IconLabel') ? (
icon={(actualDisplayMode === 'IconOnly' || actualDisplayMode === 'IconLabel') ? (
<>
{Types.isString(icon) ? (
<span className='anticon'>
Expand All @@ -158,7 +158,7 @@ export const ActionMenuItem = React.memo((props: ActionProps & MenuItemProps) =>
const ButtonContent = ({ displayMode, label, icon }: { icon: string | JSX.Element; label: string; displayMode: ActionDisplayMode }) => {
return (
<>
{(displayMode === 'Icon' || displayMode === 'IconLabel') &&
{(displayMode === 'IconOnly' || displayMode === 'IconLabel') &&
<>
{Types.isString(icon) ? (
<i className={icon} />
Expand Down
2 changes: 1 addition & 1 deletion src/wireframes/components/context-menu/ContextMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import { Menu } from 'antd';
import * as React from 'react';
import { texts } from '@app/texts';
import { ActionMenuItem, useAlignment, useClipboard, useGrouping, useRemove } from '../actions';
import { ActionMenuItem, useAlignment, useClipboard, useGrouping, useRemove } from './../actions';

export interface ContextMenuProps {
onClick?: () => void;
Expand Down
2 changes: 1 addition & 1 deletion src/wireframes/components/menu/ClipboardMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/

import * as React from 'react';
import { ActionMenuButton, useClipboard } from '../actions';
import { ActionMenuButton, useClipboard } from './../actions';

export const ClipboardMenu = React.memo(() => {
const forClipboard = useClipboard();
Expand Down
Loading

0 comments on commit c80dd68

Please sign in to comment.