Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/JS-5752: Url preview logic #1065

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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: 5 additions & 1 deletion src/scss/block/chat/attachment.scss
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
.descr { display: flex; flex-direction: row; gap: 0px 6px; align-items: center; color: var(--color-text-secondary); }
}

.attachment.isBookmark { width: unset !important; min-width: unset; height: unset; }
.attachment.isBookmark { min-width: unset; height: unset; }
.attachment.isBookmark {
.inner { display: flex; flex-direction: column; padding: 16px; gap: 8px 0px; width: 100%; max-width: 360px; }
.inner {
Expand Down Expand Up @@ -73,6 +73,10 @@
.attachment { width: 540px; }
}

.attachments.isSingle.isBookmark {
.attachment { width: 360px; }
}

/* Layouts */

.attachments.withLayout { gap: 4px; }
Expand Down
3 changes: 3 additions & 0 deletions src/ts/component/block/chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,9 @@ const BlockChat = observer(class BlockChat extends React.Component<I.BlockCompon
noDeps: true,
keys: U.Data.chatRelationKeys(),
}, (message: any) => {
if (message.error.code) {
return;
};
message.records.forEach(it => S.Detail.update(rootId, { id: it.id, details: it }, false));

if (callBack) {
Expand Down
5 changes: 3 additions & 2 deletions src/ts/component/block/chat/attachment/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { I, U, S, J, Action } from 'Lib';
interface Props {
object: any;
showAsFile?: boolean;
bookmarkAsDefault?: boolean;
onRemove: (id: string) => void;
onPreview?: (data: any) => void;
};
Expand All @@ -27,7 +28,7 @@ const ChatAttachment = observer(class ChatAttachment extends React.Component<Pro
};

render () {
const { object, showAsFile } = this.props;
const { object, showAsFile, bookmarkAsDefault } = this.props;
const mime = String(object.mime || '');
const cn = [ 'attachment' ];

Expand Down Expand Up @@ -87,7 +88,7 @@ const ChatAttachment = observer(class ChatAttachment extends React.Component<Pro
};

case I.ObjectLayout.Bookmark: {
content = this.renderBookmark();
content = bookmarkAsDefault ? this.renderDefault() : this.renderBookmark();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not understand how this should work

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i pass bookmarkAsDefault=true in case there are more than 1 attachment in the message and for all attachments in the message form

break;
};
};
Expand Down
70 changes: 36 additions & 34 deletions src/ts/component/block/chat/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,11 @@ const ChatForm = observer(class ChatForm extends React.Component<Props, State> {
>
{attachments.map(item => (
<SwiperSlide key={item.id}>
<Attachment object={item} onRemove={this.onAttachmentRemove} />
<Attachment
object={item}
onRemove={this.onAttachmentRemove}
bookmarkAsDefault={true}
/>
</SwiperSlide>
))}
</Swiper>
Expand Down Expand Up @@ -450,51 +454,48 @@ const ChatForm = observer(class ChatForm extends React.Component<Props, State> {
onPaste (e: any) {
e.preventDefault();

const { from } = this.range;
const { from, to } = this.range;
const cb = e.clipboardData || e.originalEvent.clipboardData;
const text = U.Common.normalizeLineEndings(String(cb.getData('text/plain') || ''));
const electron = U.Common.getElectron();
const list = U.Common.getDataTransferFiles((e.clipboardData || e.originalEvent.clipboardData).items).map((it: File) => this.getObjectFromFile(it)).filter(it => {
return !electron.isDirectory(it.path);
});
const value = U.Common.stringInsert(this.getTextValue(), text, from, to);

let value = this.getTextValue();
let url = U.Common.matchUrl(text);
let isLocal = false;
let to = this.range.to;
this.range = { from: to, to: to + text.length };
this.refEditable.setValue(value);
this.refEditable.setRange(this.range);
this.refEditable.placeholderCheck();

if (!url) {
url = U.Common.matchLocalPath(text);
isLocal = true;
if (list.length) {
this.addAttachments(list);
};

if (url) {
const param = isLocal ? `file://${url}` : url;

if (from == to) {
value = U.Common.stringInsert(value, url + ' ', from, from);
to = from + url.length;
};
this.checkUrls();
this.onInput();
};

this.marks = Mark.adjust(this.marks, from - 1, url.length + 1);
this.marks.push({ type: I.MarkType.Link, range: { from, to }, param});
this.updateMarkup(value, to + 1, to + 1);
this.addBookmark(param);
} else {
value = U.Common.stringInsert(value, text, from, to);

to = to + text.length;
this.range = { from: to, to };
this.refEditable.setValue(value);
this.refEditable.setRange(this.range);
this.refEditable.placeholderCheck();
checkUrls () {
const text = this.getTextValue();
const urls = U.Common.getUrlsFromText(text);
if (!urls.length) {
return;
};

if (list.length) {
this.addAttachments(list);
};
this.removeBookmarks();

this.onInput();
window.setTimeout(() => {
for (const url of urls) {
const { from, to, isLocal, value } = url;
const param = isLocal ? `file://${value}` : value;

this.marks = Mark.adjust(this.marks, from - 1, value.length + 1);
this.marks.push({ type: I.MarkType.Link, range: { from, to }, param});
this.addBookmark(param, true);
};
this.updateMarkup(text, this.range.to + 1, this.range.to + 1);
}, 150);
Comment on lines +488 to +498

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

setTimeout? Looks like workaround.

};

canDrop (e: any): boolean {
Expand Down Expand Up @@ -551,7 +552,7 @@ const ChatForm = observer(class ChatForm extends React.Component<Props, State> {
this.setState({ attachments: this.checkLimit('attachments', list) }, callBack);
};

addBookmark (url: string) {
addBookmark (url: string, fromText?: boolean) {
const add = (param: any) => {
const { title, description, url } = param;
const item = {
Expand All @@ -562,6 +563,7 @@ const ChatForm = observer(class ChatForm extends React.Component<Props, State> {
source: url,
isTmp: true,
timestamp: U.Date.now(),
fromText
};
this.addAttachments([ item ]);
};
Expand All @@ -577,7 +579,7 @@ const ChatForm = observer(class ChatForm extends React.Component<Props, State> {

removeBookmarks () {
const attachments = this.state.attachments || [];
const bookmarks = attachments.filter(it => it.layout == I.ObjectLayout.Bookmark);
const bookmarks = attachments.filter(it => (it.layout == I.ObjectLayout.Bookmark) && it.fromText);

let filtered = attachments;
bookmarks.forEach(it => {
Expand Down
1 change: 1 addition & 0 deletions src/ts/component/block/chat/message/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ const ChatMessage = observer(class ChatMessage extends React.Component<I.ChatMes
onRemove={() => this.onAttachmentRemove(item.id)}
onPreview={(preview) => this.onPreview(preview)}
showAsFile={!attachmentsLayout}
bookmarkAsDefault={attachments.length > 1}
/>
))}
</div>
Expand Down
18 changes: 18 additions & 0 deletions src/ts/lib/util/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -712,6 +712,24 @@ class UtilCommon {
return !((y1 + h1 < y2) || (y1 > y2 + h2) || (x1 + w1 < x2) || (x1 > x2 + w2));
};

getUrlsFromText (text: string): any[] {
const urls = [];
const words = text.split(/[\s\r?\n]+/);

let offset = 0;

for (const word of words) {
if (this.matchUrl(word) || this.matchLocalPath(word)) {
const from = text.substring(offset).indexOf(word) + offset;

offset = from + word.length;
urls.push({ value: word, from, to: offset, isLocal: !!this.matchLocalPath(word) });
};
};

return urls;
};

matchUrl (s: string): string {
const m = String(s || '').match(/^(?:[a-z]+:(?:\/\/)?)([^\s\/\?#]+)([^\s\?#]+)(?:\?([^#\s]*))?(?:#([^\s]*))?$/gi);
return (m && m.length) ? m[0] : '';
Expand Down
Loading