Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions src/application/slate-yjs/command/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,7 @@ export const CustomEditor = {
},

setBlockData<T = BlockData>(editor: YjsEditor, blockId: string, updateData: T, select?: boolean) {

if(editor.readOnly) {
return;
}


const block = getBlock(blockId, editor.sharedRoot);
const oldData = dataStringTOJson(block.get(YjsEditorKey.block_data));
const newData = {
Expand Down
18 changes: 15 additions & 3 deletions src/components/_shared/emoji-picker/EmojiPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,22 @@ interface Props {
onEscape?: () => void;
defaultEmoji?: string;
hideRemove?: boolean;
size?: [number, number];
}

export function EmojiPicker ({ defaultEmoji, onEscape, ...props }: Props) {
export function EmojiPicker({ defaultEmoji, onEscape, size, ...props }: Props) {
const { skin, onSkinChange, emojiCategories, setSearchValue, searchValue, onSelect, loading, isEmpty } =
useLoadEmojiData(props);

return (
<div tabIndex={0} className={'emoji-picker flex h-[360px] max-h-[70vh] flex-col p-4 pt-2'}>
<div
style={{
width: size ? size[0] : undefined,
height: size ? size[1] : undefined,
}}
tabIndex={0}
className={'emoji-picker flex h-[360px] max-h-[70vh] flex-col p-4 pt-2'}
>
<EmojiPickerHeader
onEmojiSelect={onSelect}
skin={skin}
Expand All @@ -32,7 +40,11 @@ export function EmojiPicker ({ defaultEmoji, onEscape, ...props }: Props) {
<CircularProgress />
</div>
) : isEmpty ? (
<img src={emptyImageSrc} alt={'No data found'} className={'mx-auto h-[200px]'} />
<img
src={emptyImageSrc}
alt={'No data found'}
className={'mx-auto h-[200px]'}
/>
) : (
<EmojiPickerCategories
defaultEmoji={defaultEmoji}
Expand Down
12 changes: 6 additions & 6 deletions src/components/_shared/file-dropzone/FileDropzone.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ interface FileDropzoneProps {
placeholder?: string | React.ReactNode;
}

function FileDropzone ({
function FileDropzone({
onChange,
accept,
multiple,
Expand All @@ -26,8 +26,8 @@ function FileDropzone ({
const handleFiles = (files: FileList) => {
const fileArray = Array.from(files);

if (onChange) {
if (!multiple && fileArray.length > 1) {
if(onChange) {
if(!multiple && fileArray.length > 1) {
onChange(fileArray.slice(0, 1));
} else {
onChange(fileArray);
Expand All @@ -41,7 +41,7 @@ function FileDropzone ({
event.stopPropagation();
setDragging(false);

if (event.dataTransfer.files && event.dataTransfer.files.length > 0) {
if(event.dataTransfer.files && event.dataTransfer.files.length > 0) {
handleFiles(event.dataTransfer.files);
event.dataTransfer.clearData();
}
Expand All @@ -64,15 +64,15 @@ function FileDropzone ({
};

const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
if (event.target.files) {
if(event.target.files) {
handleFiles(event.target.files);
event.target.value = '';
}
};

return (
<div
className={'w-full cursor-pointer hover:border-fill-active px-4 hover:bg-bg-body h-[160px] rounded-xl border border-dashed border-line-border flex flex-col bg-bg-base'}
className={'w-full cursor-pointer hover:border-fill-active px-4 hover:bg-bg-body min-h-[160px] h-full rounded-xl border border-dashed border-line-border flex flex-col justify-center bg-bg-base'}
onDrop={handleDrop}
onDragOver={handleDragOver}
onDragLeave={handleDragLeave}
Expand Down
36 changes: 22 additions & 14 deletions src/components/_shared/icon-picker/IconPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,14 @@ const ICONS_PER_ROW = 9;
const ROW_HEIGHT = 42;
const CATEGORY_HEIGHT = 42;

function IconPicker ({
function IconPicker({
onSelect,
onEscape,
size,
}: {
onSelect: (icon: { value: string, color: string, content: string }) => void;
onEscape?: () => void;
size?: [number, number];
}) {
const { t } = useTranslation();
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
Expand All @@ -36,8 +38,8 @@ function IconPicker ({
> | undefined>(undefined);
const [searchValue, setSearchValue] = React.useState('');
const filteredIcons = React.useMemo(() => {
if (!icons) return {};
if (!searchValue) return icons;
if(!icons) return {};
if(!searchValue) return icons;
const filtered = Object.fromEntries(
Object.entries(icons).map(([category, icons]) => [
category,
Expand All @@ -54,7 +56,7 @@ function IconPicker ({
}, [icons, searchValue]);

const rowData = React.useMemo(() => {
if (!filteredIcons) return [];
if(!filteredIcons) return [];

const rows: Array<{
type: 'category' | 'icons';
Expand All @@ -69,14 +71,14 @@ function IconPicker ({
}> = [];

Object.entries(filteredIcons).forEach(([category, icons]) => {
if (icons.length === 0) return;
if(icons.length === 0) return;

rows.push({
type: 'category',
category: category.replaceAll('_', ' '),
});

for (let i = 0; i < icons.length; i += ICONS_PER_ROW) {
for(let i = 0; i < icons.length; i += ICONS_PER_ROW) {
rows.push({
type: 'icons',
icons: icons.slice(i, i + ICONS_PER_ROW).map((icon) => ({
Expand Down Expand Up @@ -108,7 +110,7 @@ function IconPicker ({
}) => {
const row = data[index];

if (row.type === 'category') {
if(row.type === 'category') {
return (
<div
style={style}
Expand All @@ -119,7 +121,7 @@ function IconPicker ({
);
}

if (!row.icons) return null;
if(!row.icons) return null;

return (
<div
Expand Down Expand Up @@ -152,7 +154,13 @@ function IconPicker ({
}, []);

return (
<div className={'flex h-[360px] max-h-[70vh] flex-col p-4 pt-2'}>
<div
style={{
width: size ? size[0] : undefined,
height: size ? size[1] : undefined,
}}
className={'flex h-[360px] max-h-[70vh] flex-col p-4 pt-2'}
>
<div className={'px-0.5 py-2'}>
<div className={'search-input flex items-end justify-between gap-2'}>
<OutlinedInput
Expand All @@ -162,7 +170,7 @@ function IconPicker ({
setSearchValue(e.target.value);
}}
onKeyUp={(e) => {
if (e.key === 'Escape' && onEscape) {
if(e.key === 'Escape' && onEscape) {
onEscape();
}
}}
Expand All @@ -185,7 +193,7 @@ function IconPicker ({
variant={'outlined'}
color={'inherit'}
className={'h-9 w-9 min-w-[36px] px-0 py-0'}
onClick={async () => {
onClick={async() => {
const icon = await randomIcon();
const color = randomColor(IconColors);

Expand Down Expand Up @@ -242,7 +250,7 @@ function IconPicker ({
anchorEl={anchorEl}
onClose={() => setAnchorEl(null)}
onKeyDown={(e) => {
if (e.key === 'Escape') {
if(e.key === 'Escape') {
setAnchorEl(null);
}
}}
Expand All @@ -255,12 +263,12 @@ function IconPicker ({
color={'inherit'}
className={'h-9 w-9 min-w-[36px] px-0 py-0'}
onClick={() => {
if (!selectIcon) return;
if(!selectIcon) return;
const [groupName, iconName] = selectIcon.split('/');

const category = icons?.[groupName as ICON_CATEGORY];

if (!category) return;
if(!category) return;

const content = category.find((icon) => icon.name === iconName)?.content;

Expand Down
6 changes: 4 additions & 2 deletions src/components/_shared/image-upload/UploadImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const ALLOWED_IMAGE_EXTENSIONS = ['jpg', 'jpeg', 'png', 'gif', 'svg', 'we

export function UploadImage({ onDone, uploadAction }: {
onDone?: (url: string) => void;
uploadAction?: (file: File) => Promise<string>
uploadAction?: (file: File) => Promise<string>;
}) {
const { t } = useTranslation();
const [loading, setLoading] = React.useState(false);
Expand Down Expand Up @@ -38,7 +38,9 @@ export function UploadImage({ onDone, uploadAction }: {
}, [onDone, uploadAction]);

return (
<div className={'px-4 pb-4'}>
<div
className={'px-4 pb-4 h-full'}
>
<FileDropzone
placeholder={t('fileDropzone.dropFile')}
onChange={handleFileChange}
Expand Down
8 changes: 4 additions & 4 deletions src/components/_shared/outline/OutlineItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ function OutlineItem({ view, level = 0, width, navigateToView, selectedViewId, v
const renderItem = useCallback((item: View) => {
return (
<div
className={`flex ${variant === UIVariant.App ? 'folder-view-item' : ''} h-fit my-0.5 w-full justify-between gap-2`}
className={`flex ${variant === UIVariant.App ? 'folder-view-item' : ''} h-fit my-0.5 w-full justify-between`}
>
<div
style={{
Expand All @@ -42,7 +42,7 @@ function OutlineItem({ view, level = 0, width, navigateToView, selectedViewId, v
}}
id={`${variant}-view-${item.view_id}`}
className={
'flex items-center min-h-[34px] w-full gap-0.5 rounded-[8px] py-1.5 px-0.5 text-sm hover:bg-content-blue-50 focus:bg-content-blue-50 focus:outline-none'
'flex items-center min-h-[30px] w-full gap-0.5 rounded-[8px] px-0.5 text-sm hover:bg-content-blue-50 focus:bg-content-blue-50 focus:outline-none'
}
>
{item.children?.length ? getIcon() : null}
Expand All @@ -54,7 +54,7 @@ function OutlineItem({ view, level = 0, width, navigateToView, selectedViewId, v
level={level}
setIsExpanded={setIsExpanded}
/>
{item.is_private && <PrivateIcon className={'h-4 w-4 text-text-caption'}/>}
{item.is_private && <PrivateIcon className={'h-4 w-4 text-text-caption'} />}
</div>
</div>
);
Expand All @@ -64,7 +64,7 @@ function OutlineItem({ view, level = 0, width, navigateToView, selectedViewId, v

const renderChildren = useMemo(() => {
return <div
className={'flex transform flex-col gap-2 transition-all'}
className={'flex transform flex-col transition-all'}
style={{
display: isExpanded ? 'block' : 'none',
}}
Expand Down
10 changes: 9 additions & 1 deletion src/components/_shared/view-icon/ChangeIconPopover.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ function ChangeIconPopover({
value={value}
>
<IconPicker
size={[400, 360]}
onEscape={handleClose}
onSelect={(icon) => {
onSelectIcon?.({
Expand All @@ -131,6 +132,7 @@ function ChangeIconPopover({
value={value}
>
<EmojiPicker
size={[400, 360]}
onEmojiSelect={(emoji: string) => {
onSelectIcon?.({
ty: ViewIconType.Emoji,
Expand All @@ -145,7 +147,13 @@ function ChangeIconPopover({
index={'upload'}
value={value}
>
<div className={'pt-4 relative pb-2'}>
<div
style={{
width: 400,
height: 360,
}}
className={'relative pt-4 pb-2'}
>
<UploadImage
onDone={(url) => {
onSelectIcon?.({
Expand Down
14 changes: 4 additions & 10 deletions src/components/editor/components/blocks/toggle-list/ToggleIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,17 @@ import { CustomEditor } from '@/application/slate-yjs/command';
import { ToggleListNode } from '@/components/editor/editor.type';
import React, { useCallback } from 'react';
import { ReactComponent as ExpandSvg } from '@/assets/drop_menu_show.svg';
import { useReadOnly, useSlateStatic } from 'slate-react';
import { Element } from 'slate';
import { useSlateStatic } from 'slate-react';

function ToggleIcon ({ block, className }: { block: ToggleListNode; className: string }) {
function ToggleIcon({ block, className }: { block: ToggleListNode; className: string }) {
const { collapsed } = block.data;
const editor = useSlateStatic();
const readOnly = useReadOnly() || editor.isElementReadOnly(block as unknown as Element);

const handleClick = useCallback((e: React.MouseEvent) => {
if (readOnly) {
return;
}

e.stopPropagation();
e.preventDefault();
CustomEditor.toggleToggleList(editor as YjsEditor, block.blockId);
}, [block.blockId, editor, readOnly]);
}, [block.blockId, editor]);

return (
<span
Expand All @@ -31,7 +25,7 @@ function ToggleIcon ({ block, className }: { block: ToggleListNode; className: s
e.preventDefault();
handleClick(e);
}}
className={`${className} ${readOnly ? '' : 'cursor-pointer hover:text-fill-default'} pr-1 toggle-icon`}
className={`${className} cursor-pointer hover:text-fill-default pr-1 toggle-icon`}
>
{collapsed ? <ExpandSvg className={'-rotate-90 transform'} /> : <ExpandSvg />}
</span>
Expand Down
7 changes: 6 additions & 1 deletion src/components/login/Login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,12 @@ export function Login({ redirectTo }: { redirectTo: string }) {
.
</div>
<Divider className={'w-[300px] max-w-full border-line-divider'} />
<div className={'text-text-title text-xs font-medium cursor-pointer opacity-60 hover:opacity-100 w-full gap-2 flex items-center justify-center'}>
<div
onClick={() => {
window.location.href = 'https://appflowy.com';
}}
className={'text-text-title text-xs font-medium cursor-pointer opacity-60 hover:opacity-100 w-full gap-2 flex items-center justify-center'}
>
<span>{t('web.visitOurWebsite')}</span>
<ArrowRight className={'w-4 h-4'} />
</div>
Expand Down
Loading