Skip to content

Commit

Permalink
Merge branch 'feat/apps-deno-runtime' into feat/apps-logger
Browse files Browse the repository at this point in the history
  • Loading branch information
tapiarafael committed Jan 8, 2024
2 parents 5a139b2 + 86d75ce commit c91fde0
Show file tree
Hide file tree
Showing 36 changed files with 634 additions and 501 deletions.
6 changes: 6 additions & 0 deletions .changeset/big-teachers-change.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@rocket.chat/meteor": minor
"@rocket.chat/ui-contexts": minor
---

Add the possibility to hide some elements through postMessage events.
5 changes: 5 additions & 0 deletions .changeset/clean-melons-return.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": patch
---

Fixed image dropping from another browser window creates two upload dialogs in some OS and browsers
5 changes: 5 additions & 0 deletions .changeset/itchy-zoos-appear.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@rocket.chat/meteor": minor
---

Fixes an issue where avatars are not being disabled based on preference on quote attachments
15 changes: 0 additions & 15 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -724,21 +724,6 @@ jobs:
# Makes build fail if the release isn't there
curl --fail https://releases.rocket.chat/$RC_VERSION/info
- name: RedHat Registry
if: github.event_name == 'release'
env:
REDHAT_REGISTRY_PID: ${{ secrets.REDHAT_REGISTRY_PID }}
REDHAT_REGISTRY_KEY: ${{ secrets.REDHAT_REGISTRY_KEY }}
run: |
GIT_TAG="${GITHUB_REF#*tags/}"
curl -X POST \
https://connect.redhat.com/api/v2/projects/$REDHAT_REGISTRY_PID/build \
-H "Authorization: Bearer $REDHAT_REGISTRY_KEY" \
-H 'Cache-Control: no-cache' \
-H 'Content-Type: application/json' \
-d '{"tag":"'$GIT_TAG'"}'
trigger-dependent-workflows:
runs-on: ubuntu-latest
if: github.event_name == 'release'
Expand Down
44 changes: 0 additions & 44 deletions apps/meteor/.docker/Dockerfile.rhel

This file was deleted.

3 changes: 2 additions & 1 deletion apps/meteor/app/ui-utils/client/lib/messageBox.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type { IMessage, IRoom } from '@rocket.chat/core-typings';
import type { Keys as IconName } from '@rocket.chat/icons';
import type { TranslationKey } from '@rocket.chat/ui-contexts';

import type { ChatAPI } from '../../../../client/lib/chats/ChatAPI';

export type MessageBoxAction = {
label: TranslationKey;
id: string;
icon?: string;
icon: IconName;
action: (params: { rid: IRoom['_id']; tmid?: IMessage['_id']; event: Event; chat: ChatAPI }) => void;
condition?: () => boolean;
};
Expand Down
196 changes: 124 additions & 72 deletions apps/meteor/app/utils/client/lib/SDKClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,114 +45,166 @@ const isChangedCollectionPayload = (
return true;
};

export const createSDK = (rest: RestClientInterface) => {
const ev = new Emitter();
type EventMap<N extends StreamNames = StreamNames, K extends StreamKeys<N> = StreamKeys<N>> = {
[key in `stream-${N}/${K}`]: StreamerCallbackArgs<N, K>;
};

type StreamMapValue = {
stop: () => void;
onChange: ReturnType<ClientStream['subscribe']>['onChange'];
ready: () => Promise<void>;
isReady: boolean;
unsubList: Set<() => void>;
};

const createNewMeteorStream = (streamName: StreamNames, key: StreamKeys<StreamNames>, args: unknown[]): StreamMapValue => {
const ee = new Emitter();
const meta = {
ready: false,
};
const sub = Meteor.connection.subscribe(
`stream-${streamName}`,
key,
{ useCollection: false, args },
{
onReady: (args: any) => {
meta.ready = true;
ee.emit('ready', [undefined, args]);
},
onError: (err: any) => {
console.error(err);
ee.emit('ready', [err]);
},
},
);

const onChange: ReturnType<ClientStream['subscribe']>['onChange'] = (cb) => {
if (meta.ready) {
cb({
msg: 'ready',

subs: [],
});
return;
}
ee.once('ready', ([error, result]) => {
if (error) {
cb({
msg: 'nosub',

id: '',
error,
});
return;
}

const streams = new Map<string, (...args: unknown[]) => void>();
cb(result);
});
};

const ready = () => {
if (meta.ready) {
return Promise.resolve();
}
return new Promise<void>((r) => {
ee.once('ready', r);
});
};

return {
stop: sub.stop,
onChange,
ready,
get isReady() {
return meta.ready;
},
unsubList: new Set(),
};
};

const createStreamManager = () => {
// Emitter that replicates stream messages to registered callbacks
const streamProxy = new Emitter<EventMap>();

// Collection of unsubscribe callbacks for each stream.
// const proxyUnsubLists = new Map<string, Set<() => void>>();

const streams = new Map<string, StreamMapValue>();

Meteor.connection._stream.on('message', (rawMsg: string) => {
const msg = DDPCommon.parseDDP(rawMsg);
if (!isChangedCollectionPayload(msg)) {
return;
}
ev.emit(`${msg.collection}/${msg.fields.eventName}`, msg.fields.args);
streamProxy.emit(`${msg.collection}/${msg.fields.eventName}` as any, msg.fields.args as any);
});

const stream: SDK['stream'] = <N extends StreamNames, K extends StreamKeys<N>>(
name: N,
data: [key: K, ...args: unknown[]],
cb: (...args: StreamerCallbackArgs<N, K>) => void,
callback: (...args: StreamerCallbackArgs<N, K>) => void,
_options?: {
retransmit?: boolean | undefined;
retransmitToSelf?: boolean | undefined;
},
): ReturnType<ClientStream['subscribe']> => {
const [key, ...args] = data;
const streamName = `stream-${name}`;
const streamKey = `${streamName}/${key}`;

const ee = new Emitter();
const eventLiteral = `stream-${name}/${key}` as const;

const meta = {
ready: false,
const proxyCallback = (args?: unknown): void => {
if (!args || !Array.isArray(args)) {
throw new Error('Invalid streamer callback');
}
callback(...(args as StreamerCallbackArgs<N, K>));
};

const sub = Meteor.connection.subscribe(
streamName,
key,
{ useCollection: false, args },
{
onReady: (args: any) => {
meta.ready = true;
ee.emit('ready', [undefined, args]);
},
onError: (err: any) => {
console.error(err);
ee.emit('ready', [err]);
},
},
);
streamProxy.on(eventLiteral, proxyCallback);

const onChange: ReturnType<ClientStream['subscribe']>['onChange'] = (cb) => {
if (meta.ready) {
cb({
msg: 'ready',
const stop = (): void => {
streamProxy.off(eventLiteral, proxyCallback);

subs: [],
});
// If someone is still listening, don't unsubscribe
if (streamProxy.has(eventLiteral)) {
return;
}
ee.once('ready', ([error, result]) => {
if (error) {
cb({
msg: 'nosub',

id: '',
error,
});
return;
}

cb(result);
});
};

const ready = () => {
if (meta.ready) {
return Promise.resolve();
if (stream) {
stream.stop();
streams.delete(eventLiteral);
}
return new Promise<void>((r) => {
ee.once('ready', r);
});
};

const removeEv = ev.on(`${streamKey}`, (args) => cb(...args));

const stop = () => {
streams.delete(`${streamKey}`);
sub.stop();
removeEv();
};

streams.set(`${streamKey}`, stop);
const stream = streams.get(eventLiteral) || createNewMeteorStream(name, key, args);
stream.unsubList.add(stop);
if (!streams.has(eventLiteral)) {
streams.set(eventLiteral, stream);
}

return {
id: '',
name,
params: data as any,
stop,
ready,
onChange,
get isReady() {
return meta.ready;
},
ready: stream.ready,
onChange: stream.onChange,
isReady: stream.isReady,
};
};

const stop = (name: string, key: string) => {
const streamKey = `stream-${name}/${key}`;
const stop = streams.get(streamKey);
if (stop) {
stop();
const stopAll = (streamName: string, key: string) => {
const stream = streams.get(`stream-${streamName}/${key}`);

if (stream) {
stream.unsubList.forEach((stop) => stop());
}
};

return { stream, stopAll };
};

export const createSDK = (rest: RestClientInterface) => {
const { stream, stopAll } = createStreamManager();

const publish = (name: string, args: unknown[]) => {
Meteor.call(`stream-${name}`, ...args);
};
Expand All @@ -163,7 +215,7 @@ export const createSDK = (rest: RestClientInterface) => {

return {
rest,
stop,
stop: stopAll,
stream,
publish,
call,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { MessageQuoteAttachment } from '@rocket.chat/core-typings';
import { css } from '@rocket.chat/css-in-js';
import { Box, Palette } from '@rocket.chat/fuselage';
import { useUserPreference } from '@rocket.chat/ui-contexts';
import type { ReactElement } from 'react';
import React from 'react';

Expand Down Expand Up @@ -37,6 +38,7 @@ type QuoteAttachmentProps = {

export const QuoteAttachment = ({ attachment }: QuoteAttachmentProps): ReactElement => {
const formatTime = useTimeAgo();
const displayAvatarPreference = useUserPreference('displayAvatars');

return (
<>
Expand All @@ -50,7 +52,7 @@ export const QuoteAttachment = ({ attachment }: QuoteAttachmentProps): ReactElem
borderInlineStartColor='light'
>
<AttachmentAuthor>
<AttachmentAuthorAvatar url={attachment.author_icon} />
{displayAvatarPreference && <AttachmentAuthorAvatar url={attachment.author_icon} />}
<AttachmentAuthorName
{...(attachment.author_link && { is: 'a', href: attachment.author_link, target: '_blank', color: 'hint' })}
>
Expand Down
Loading

0 comments on commit c91fde0

Please sign in to comment.