diff --git a/.changeset/chilled-chicken-drop.md b/.changeset/chilled-chicken-drop.md
new file mode 100644
index 0000000000000..139b3c00c82dd
--- /dev/null
+++ b/.changeset/chilled-chicken-drop.md
@@ -0,0 +1,6 @@
+---
+"@rocket.chat/meteor": patch
+"@rocket.chat/ddp-streamer": patch
+---
+
+Adds deprecation warning on `livechat:setupConnection`
diff --git a/.changeset/clever-cycles-sing.md b/.changeset/clever-cycles-sing.md
new file mode 100644
index 0000000000000..d52d892103f1d
--- /dev/null
+++ b/.changeset/clever-cycles-sing.md
@@ -0,0 +1,5 @@
+---
+"@rocket.chat/meteor": patch
+---
+
+Adds deprecation warning on `sendFileLivechatMessage`
diff --git a/.changeset/lemon-kings-approve.md b/.changeset/lemon-kings-approve.md
new file mode 100644
index 0000000000000..1a6999c545273
--- /dev/null
+++ b/.changeset/lemon-kings-approve.md
@@ -0,0 +1,5 @@
+---
+'@rocket.chat/meteor': patch
+---
+
+Fixes an issue where messages are not being translated immediately in omnichannel rooms
diff --git a/.changeset/rare-schools-laugh.md b/.changeset/rare-schools-laugh.md
new file mode 100644
index 0000000000000..69cd0af9040d6
--- /dev/null
+++ b/.changeset/rare-schools-laugh.md
@@ -0,0 +1,5 @@
+---
+"@rocket.chat/meteor": patch
+---
+
+Fixes real-time monitoring displaying incorrect data
diff --git a/.changeset/slow-tomatoes-try.md b/.changeset/slow-tomatoes-try.md
new file mode 100644
index 0000000000000..91b762e4f8bf6
--- /dev/null
+++ b/.changeset/slow-tomatoes-try.md
@@ -0,0 +1,5 @@
+---
+'@rocket.chat/meteor': patch
+---
+
+Fixes an issue where pagination is not working properly in โusers in roleโ table
diff --git a/apps/meteor/app/autotranslate/client/lib/autotranslate.ts b/apps/meteor/app/autotranslate/client/lib/autotranslate.ts
index 3cea977c8b4e4..76b45d04e18fa 100644
--- a/apps/meteor/app/autotranslate/client/lib/autotranslate.ts
+++ b/apps/meteor/app/autotranslate/client/lib/autotranslate.ts
@@ -148,7 +148,6 @@ export const createAutoTranslateMessageStreamHandler = (): ((message: ITranslate
(record) => record._id === message._id,
({ autoTranslateFetching: _, ...record }) => ({
...record,
- autoTranslateShowInverse: true,
}),
);
delete AutoTranslate.messageIdsToWait[message._id];
diff --git a/apps/meteor/app/livechat/client/lib/chartHandler.ts b/apps/meteor/app/livechat/client/lib/chartHandler.ts
index 55f4baafd5924..9e86c5d323513 100644
--- a/apps/meteor/app/livechat/client/lib/chartHandler.ts
+++ b/apps/meteor/app/livechat/client/lib/chartHandler.ts
@@ -209,3 +209,12 @@ export const updateChart = async (
chart.update();
};
+
+export const resetChart = (chart: chartjs.Chart): void => {
+ chart.data.labels = [];
+ chart.data.datasets.forEach((dataset) => {
+ dataset.data = [];
+ });
+
+ chart.update();
+};
diff --git a/apps/meteor/app/livechat/server/methods/sendFileLivechatMessage.ts b/apps/meteor/app/livechat/server/methods/sendFileLivechatMessage.ts
index ef12cf728c733..7369cd450a6b9 100644
--- a/apps/meteor/app/livechat/server/methods/sendFileLivechatMessage.ts
+++ b/apps/meteor/app/livechat/server/methods/sendFileLivechatMessage.ts
@@ -13,6 +13,7 @@ import { Meteor } from 'meteor/meteor';
import { sendMessageLivechat } from './sendMessageLivechat';
import { FileUpload } from '../../../file-upload/server';
+import { methodDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger';
interface ISendFileLivechatMessage {
roomId: string;
@@ -112,6 +113,7 @@ export const sendFileLivechatMessage = async ({ roomId, visitorToken, file, msgD
Meteor.methods({
async sendFileLivechatMessage(roomId, visitorToken, file, msgData = {}) {
+ methodDeprecationLogger.method('sendFileLivechatMessage', '8.0.0', '/v1/livechat/upload/:rid');
return sendFileLivechatMessage({ roomId, visitorToken, file, msgData });
},
});
diff --git a/apps/meteor/app/livechat/server/methods/setUpConnection.ts b/apps/meteor/app/livechat/server/methods/setUpConnection.ts
index d6f05c9af03f1..4aea4caa7c6fd 100644
--- a/apps/meteor/app/livechat/server/methods/setUpConnection.ts
+++ b/apps/meteor/app/livechat/server/methods/setUpConnection.ts
@@ -3,6 +3,7 @@ import type { ServerMethods } from '@rocket.chat/ddp-client';
import { check } from 'meteor/check';
import { Meteor } from 'meteor/meteor';
+import { methodDeprecationLogger } from '../../../lib/server/lib/deprecationWarningLogger';
import { notifyGuestStatusChanged } from '../lib/guests';
declare module '@rocket.chat/ddp-client' {
@@ -24,6 +25,7 @@ declare module 'meteor/meteor' {
Meteor.methods({
'livechat:setUpConnection'(data) {
+ methodDeprecationLogger.method('livechat:setUpConnection', '8.0.0', 'This functionality is no longer supported');
check(data, {
token: String,
});
diff --git a/apps/meteor/client/components/GenericTable/hooks/usePagination.ts b/apps/meteor/client/components/GenericTable/hooks/usePagination.ts
index 803752fda45ef..f7723283fd7ee 100644
--- a/apps/meteor/client/components/GenericTable/hooks/usePagination.ts
+++ b/apps/meteor/client/components/GenericTable/hooks/usePagination.ts
@@ -5,6 +5,9 @@ import { useItemsPerPage } from './useItemsPerPage';
import { useItemsPerPageLabel } from './useItemsPerPageLabel';
import { useShowingResultsLabel } from './useShowingResultsLabel';
+/**
+ * TODO: Move `usePagination` outside from `GenericTable` folder
+ */
export const usePagination = (): {
current: ReturnType[0];
setCurrent: ReturnType[1];
diff --git a/apps/meteor/client/components/UserInfo/UserInfo.spec.tsx b/apps/meteor/client/components/UserInfo/UserInfo.spec.tsx
new file mode 100644
index 0000000000000..6e2c772e368a3
--- /dev/null
+++ b/apps/meteor/client/components/UserInfo/UserInfo.spec.tsx
@@ -0,0 +1,18 @@
+import { composeStories } from '@storybook/react';
+import { render } from '@testing-library/react';
+import { axe } from 'jest-axe';
+
+import * as stories from './UserInfo.stories';
+
+const testCases = Object.values(composeStories(stories)).map((Story) => [Story.storyName || 'Story', Story]);
+test.each(testCases)(`renders %s without crashing`, async (_storyname, Story) => {
+ const { baseElement } = render();
+ expect(baseElement).toMatchSnapshot();
+});
+
+test.each(testCases)('%s should have no a11y violations', async (_storyname, Story) => {
+ const { container } = render();
+
+ const results = await axe(container);
+ expect(results).toHaveNoViolations();
+});
diff --git a/apps/meteor/client/components/UserInfo/UserInfo.stories.tsx b/apps/meteor/client/components/UserInfo/UserInfo.stories.tsx
index d6bd2cf662e1d..9e76aa0064590 100644
--- a/apps/meteor/client/components/UserInfo/UserInfo.stories.tsx
+++ b/apps/meteor/client/components/UserInfo/UserInfo.stories.tsx
@@ -1,8 +1,9 @@
import type { Meta, StoryFn } from '@storybook/react';
-import { Contextualbar } from '../Contextualbar';
+import { ContextualbarDialog } from '../Contextualbar';
import * as Status from '../UserStatus';
import UserInfo from './UserInfo';
+import { UserCardRole } from '../UserCard';
export default {
component: UserInfo,
@@ -10,32 +11,32 @@ export default {
layout: 'fullscreen',
actions: { argTypesRegex: '^on.*' },
},
- decorators: [(fn) => {fn()}],
+ decorators: [
+ (fn) => (
+
+ {fn()}
+
+ ),
+ ],
} satisfies Meta;
-const Template: StoryFn = (args) => ;
-
-export const Default = Template.bind({});
-Default.args = {
+const defaultArgs = {
name: 'Guilherme Gazzo',
username: 'guilherme.gazzo',
+ nickname: 'gazzo',
statusText: '๐ด currently working on User Card',
- bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tempus, eros convallis vulputate cursus, nisi neque eleifend libero, eget lacinia justo purus nec est. In at sodales ipsum. Sed lacinia quis purus eget pulvinar. Aenean eu pretium nunc, at aliquam magna. Praesent dignissim, tortor sed volutpat mattis, mauris diam pulvinar leo, porta commodo risus est non purus. Mauris in justo vel lorem ullamcorper hendrerit. Nam est metus, viverra a pellentesque vitae, ornare eget odio. Morbi tempor feugiat mattis. Morbi non felis tempor, aliquam justo sed, sagittis nibh. Mauris consequat ex metus. Praesent sodales sit amet nibh a vulputate. Integer commodo, mi vel bibendum sollicitudin, urna lectus accumsan ante, eget faucibus augue ex id neque. Aenean consectetur, orci a pellentesque mattis, tortor tellus fringilla elit, non ullamcorper risus nunc feugiat risus. Fusce sit amet nisi dapibus turpis commodo placerat. In tortor ante, vehicula sit amet augue et, imperdiet porta sem.',
- // actions: [, ],
- utcOffset: -3,
+ bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tempus, eros convallis vulputate cursus, nisi neque eleifend libero, eget lacinia justo purus nec est. In at sodales ipsum. Sed lacinia quis purus eget pulvinar. Aenean eu pretium nunc, at aliquam magna. Praesent dignissim, tortor sed volutpat mattis, mauris diam pulvinar leo, porta commodo risus est non purus.',
email: 'rocketchat@rocket.chat',
status: ,
+ roles: [admin, user],
};
-export const WithNickname = Template.bind({});
-WithNickname.args = {
- name: 'Guilherme Gazzo',
- username: 'guilherme.gazzo',
- statusText: '๐ด currently working on User Card',
- bio: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tempus, eros convallis vulputate cursus, nisi neque eleifend libero, eget lacinia justo purus nec est. In at sodales ipsum. Sed lacinia quis purus eget pulvinar. Aenean eu pretium nunc, at aliquam magna. Praesent dignissim, tortor sed volutpat mattis, mauris diam pulvinar leo, porta commodo risus est non purus. Mauris in justo vel lorem ullamcorper hendrerit. Nam est metus, viverra a pellentesque vitae, ornare eget odio. Morbi tempor feugiat mattis. Morbi non felis tempor, aliquam justo sed, sagittis nibh. Mauris consequat ex metus. Praesent sodales sit amet nibh a vulputate. Integer commodo, mi vel bibendum sollicitudin, urna lectus accumsan ante, eget faucibus augue ex id neque. Aenean consectetur, orci a pellentesque mattis, tortor tellus fringilla elit, non ullamcorper risus nunc feugiat risus. Fusce sit amet nisi dapibus turpis commodo placerat. In tortor ante, vehicula sit amet augue et, imperdiet porta sem.',
- // actions: [, ],
- utcOffset: -3,
- email: 'rocketchat@rocket.chat',
- status: ,
- nickname: 'Nickname',
+const Template: StoryFn = (args) => ;
+
+export const Default = Template.bind({});
+
+export const WithABACAttributes = Template.bind({});
+WithABACAttributes.args = {
+ // @ts-expect-error - abacAttributes is not yet implemented in Users properties
+ abacAttributes: ['Classified', 'Top Secret', 'Confidential'],
};
diff --git a/apps/meteor/client/components/UserInfo/UserInfo.tsx b/apps/meteor/client/components/UserInfo/UserInfo.tsx
index 4a0413d912870..58bbbc1a52ee5 100644
--- a/apps/meteor/client/components/UserInfo/UserInfo.tsx
+++ b/apps/meteor/client/components/UserInfo/UserInfo.tsx
@@ -22,6 +22,7 @@ import {
import MarkdownText from '../MarkdownText';
import UTCClock from '../UTCClock';
import { UserCardRoles } from '../UserCard';
+import UserInfoABACAttributes from './UserInfoABACAttributes';
import UserInfoAvatar from './UserInfoAvatar';
type UserInfoDataProps = Serialized<
@@ -70,6 +71,8 @@ const UserInfo = ({
canViewAllInfo,
actions,
reason,
+ // @ts-expect-error - abacAttributes is not yet implemented in Users properties
+ abacAttributes = null,
...props
}: UserInfoProps): ReactElement => {
const { t } = useTranslation();
@@ -113,7 +116,7 @@ const UserInfo = ({
)}
- {roles.length !== 0 && (
+ {roles?.length !== 0 && (
{t('Roles')}{roles}
@@ -127,10 +130,12 @@ const UserInfo = ({
)}
- {Number.isInteger(utcOffset) && (
+ {utcOffset && Number.isInteger(utcOffset) && (
{t('Local_Time')}
- {utcOffset && }
+
+
+
)}
@@ -175,6 +180,12 @@ const UserInfo = ({
)}
+ {abacAttributes?.length > 0 && (
+
+ {t('ABAC_Attributes')}
+
+
+ )}
{userCustomFields?.map(
(customField) =>
customField?.value && (
diff --git a/apps/meteor/client/components/UserInfo/UserInfoABACAttribute.tsx b/apps/meteor/client/components/UserInfo/UserInfoABACAttribute.tsx
new file mode 100644
index 0000000000000..5605bd91d7cd7
--- /dev/null
+++ b/apps/meteor/client/components/UserInfo/UserInfoABACAttribute.tsx
@@ -0,0 +1,11 @@
+import { Tag } from '@rocket.chat/fuselage';
+
+type UserInfoABACAttributeProps = {
+ attribute: string;
+};
+
+const UserInfoABACAttribute = ({ attribute }: UserInfoABACAttributeProps) => {
+ return ;
+};
+
+export default UserInfoABACAttribute;
diff --git a/apps/meteor/client/components/UserInfo/UserInfoABACAttributes.tsx b/apps/meteor/client/components/UserInfo/UserInfoABACAttributes.tsx
new file mode 100644
index 0000000000000..b9cf2870d3d64
--- /dev/null
+++ b/apps/meteor/client/components/UserInfo/UserInfoABACAttributes.tsx
@@ -0,0 +1,23 @@
+import { Box, Margins } from '@rocket.chat/fuselage';
+
+import UserInfoABACAttribute from './UserInfoABACAttribute';
+
+type UserInfoABACAttributesProps = {
+ abacAttributes: string[];
+};
+
+const UserInfoABACAttributes = ({ abacAttributes }: UserInfoABACAttributesProps) => {
+ return (
+
+
+ {abacAttributes.map((attribute, index) => (
+
+
+
+ ))}
+
+
+ );
+};
+
+export default UserInfoABACAttributes;
diff --git a/apps/meteor/client/components/UserInfo/__snapshots__/UserInfo.spec.tsx.snap b/apps/meteor/client/components/UserInfo/__snapshots__/UserInfo.spec.tsx.snap
new file mode 100644
index 0000000000000..33c5d0d0d537b
--- /dev/null
+++ b/apps/meteor/client/components/UserInfo/__snapshots__/UserInfo.spec.tsx.snap
@@ -0,0 +1,574 @@
+// Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing
+
+exports[`renders Default without crashing 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ guilherme.gazzo
+
+
+
+
+
+ currently working on User Card
+
+
+
+
+
+
+ Nickname
+
+
+ gazzo
+
+
+
+
+ Roles
+
+
+
+
+
+
+ admin
+
+
+
+
+
+
+ user
+
+
+
+
+
+
+
+
+ Username
+
+
+ guilherme.gazzo
+
+
+
+
+ Bio
+
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tempus, eros convallis vulputate cursus, nisi neque eleifend libero, eget lacinia justo purus nec est. In at sodales ipsum. Sed lacinia quis purus eget pulvinar. Aenean eu pretium nunc, at aliquam magna. Praesent dignissim, tortor sed volutpat mattis, mauris diam pulvinar leo, porta commodo risus est non purus.
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla tempus, eros convallis vulputate cursus, nisi neque eleifend libero, eget lacinia justo purus nec est. In at sodales ipsum. Sed lacinia quis purus eget pulvinar. Aenean eu pretium nunc, at aliquam magna. Praesent dignissim, tortor sed volutpat mattis, mauris diam pulvinar leo, porta commodo risus est non purus.
+
While you can keep using Rocket.Chat, your team will lose access to unlimited mobile push notifications, read receipts, marketplace apps <4>and other capabilities4>.",
+ "Cancel_subscription_message": "This workspace will downgrade to Community and lose free access to premium capabilities.
While you can keep using Rocket.Chat, your team will lose access to unlimited mobile push notifications, read receipts, marketplace apps <4>and other capabilities4>.",
"Canceled": "Canceled",
"Canned_Response_Created": "Canned Response created",
"Canned_Response_Delete_Warning": "Deleting a canned response cannot be undone.",
@@ -985,7 +987,7 @@
"Channel_to_listen_on": "Channel to listen on",
"Channel_what_is_this_channel_about": "What is this channel about?",
"Channels": "Channels",
- "Channels_added": "Channels added sucessfully",
+ "Channels_added": "Channels added successfully",
"Channels_are_where_your_team_communicate": "Channels are where your team communicate",
"Channels_list": "List of public channels",
"Chart": "Chart",
@@ -2029,6 +2031,8 @@
"Execute_Synchronization_Now": "Execute Synchronization Now",
"Exit_Full_Screen": "Exit Full Screen",
"Expand": "Expand",
+ "Expandable_message_composer": "Expandable Composer",
+ "Expandable_message_composer_description": "Expand the text input area to easily write and review longer messages without having to scroll up and down.",
"Expand_group": "Expand {{group}}",
"Expand_all": "Expand all",
"Expand_view": "Expand view",
@@ -4645,6 +4649,10 @@
"Search_Installed_Apps": "Search installed apps",
"Search_Integrations": "Search Integrations",
"Search_Messages": "Search Messages",
+ "Search_Messages_Count": {
+ "one": "Found {{count}} single result",
+ "other": "Found {{count}} results"
+ },
"Search_Page_Size": "Page Size",
"Search_Premium_Apps": "Search Premium apps",
"Search_Private_Groups": "Search Private Groups",
@@ -6590,7 +6598,7 @@
"onboarding.form.registeredServerForm.registrationKeepInformed": "By submitting this form you consent to receive more information about Rocket.Chat products, events and updates, according to our <1>privacy policy1>. You may unsubscribe at any time.",
"onboarding.form.registeredServerForm.title": "Register your workspace",
"onboarding.form.standaloneServerForm.manuallyIntegrate": "Need to manually integrate with external services",
- "onboarding.form.standaloneServerForm.publishOwnApp": "In order to send push notitications you need to compile and publish your own app to Google Play and App Store",
+ "onboarding.form.standaloneServerForm.publishOwnApp": "In order to send push notifications you need to compile and publish your own app to Google Play and App Store",
"onboarding.form.standaloneServerForm.servicesUnavailable": "Some of the services will be unavailable or will require manual setup",
"onboarding.form.standaloneServerForm.title": "Standalone Server Confirmation",
"onboarding.page.alreadyHaveAccount": "Already have an account? <1>Manage your workspaces.1>",
diff --git a/packages/media-signaling/src/definition/call/IClientMediaCall.ts b/packages/media-signaling/src/definition/call/IClientMediaCall.ts
index c7ad364808191..71b3bb5827b0d 100644
--- a/packages/media-signaling/src/definition/call/IClientMediaCall.ts
+++ b/packages/media-signaling/src/definition/call/IClientMediaCall.ts
@@ -77,6 +77,7 @@ export interface IClientMediaCall {
busy: boolean;
contact: CallContact;
+ transferredBy: CallContact | null;
audioLevel: number;
localAudioLevel: number;
diff --git a/packages/media-signaling/src/definition/signals/server/new.ts b/packages/media-signaling/src/definition/signals/server/new.ts
index 89967bd3a4fd5..92e4d9ed57ba0 100644
--- a/packages/media-signaling/src/definition/signals/server/new.ts
+++ b/packages/media-signaling/src/definition/signals/server/new.ts
@@ -15,4 +15,6 @@ export type ServerMediaSignalNewCall = {
requestedCallId?: string;
/** If this new call initiated from a transfer, this will hold the id of the call that was transferred */
replacingCallId?: string;
+ /** If this new call initiated from a transfer, this will hold the information of the user who requested the transfer */
+ transferredBy?: CallContact;
};
diff --git a/packages/media-signaling/src/lib/Call.ts b/packages/media-signaling/src/lib/Call.ts
index 8ed715cfbfafb..37e061a8a3ec4 100644
--- a/packages/media-signaling/src/lib/Call.ts
+++ b/packages/media-signaling/src/lib/Call.ts
@@ -78,6 +78,12 @@ export class ClientMediaCall implements IClientMediaCall {
return this._contact || {};
}
+ private _transferredBy: CallContact | null;
+
+ public get transferredBy(): CallContact | null {
+ return this._transferredBy;
+ }
+
private _service: CallService | null;
public get service(): CallService | null {
@@ -200,6 +206,7 @@ export class ClientMediaCall implements IClientMediaCall {
this.oldClientState = 'none';
this._ignored = false;
this._contact = null;
+ this._transferredBy = null;
this._service = null;
}
@@ -263,6 +270,7 @@ export class ClientMediaCall implements IClientMediaCall {
this._service = signal.service;
this._role = signal.role;
+ this._transferredBy = signal.transferredBy || null;
this.changeContact(signal.contact);
if (this._role === 'caller' && !this.acceptedLocally) {
diff --git a/packages/ui-client/src/hooks/useFeaturePreviewList.ts b/packages/ui-client/src/hooks/useFeaturePreviewList.ts
index 840f3956c6059..f8fef33c53900 100644
--- a/packages/ui-client/src/hooks/useFeaturePreviewList.ts
+++ b/packages/ui-client/src/hooks/useFeaturePreviewList.ts
@@ -5,7 +5,8 @@ export type FeaturesAvailable =
| 'enable-timestamp-message-parser'
| 'contextualbarResizable'
| 'newNavigation'
- | 'secondarySidebar';
+ | 'secondarySidebar'
+ | 'expandableMessageComposer';
export type FeaturePreviewProps = {
name: FeaturesAvailable;
@@ -73,6 +74,15 @@ export const defaultFeaturesPreview: FeaturePreviewProps[] = [
value: true,
},
},
+ {
+ name: 'expandableMessageComposer',
+ i18n: 'Expandable_message_composer',
+ description: 'Expandable_message_composer_description',
+ imageUrl: 'images/featurePreview/expandable-composer.png',
+ group: 'Message',
+ value: false,
+ enabled: true,
+ },
];
export const enabledDefaultFeatures = defaultFeaturesPreview.filter((feature) => feature.enabled);
diff --git a/packages/ui-composer/src/MessageComposer/MessageComposer.stories.tsx b/packages/ui-composer/src/MessageComposer/MessageComposer.stories.tsx
index b15ddb1a3ea0f..3c03bed370ea0 100644
--- a/packages/ui-composer/src/MessageComposer/MessageComposer.stories.tsx
+++ b/packages/ui-composer/src/MessageComposer/MessageComposer.stories.tsx
@@ -12,6 +12,7 @@ import {
MessageComposerToolbarSubmit,
MessageComposerSkeleton,
MessageComposerHint,
+ MessageComposerInputExpandable,
} from '.';
export default {
@@ -48,6 +49,21 @@ export const Default: StoryFn = () => (
);
+export const Expandable: StoryFn = () => (
+
+
+
+
+
+
+);
+
export const ToolbarActions: StoryFn = () => ;
export const WithHints: StoryFn = () => (
diff --git a/packages/ui-composer/src/MessageComposer/MessageComposerInputExpandable.spec.tsx b/packages/ui-composer/src/MessageComposer/MessageComposerInputExpandable.spec.tsx
new file mode 100644
index 0000000000000..804c21b9bba3a
--- /dev/null
+++ b/packages/ui-composer/src/MessageComposer/MessageComposerInputExpandable.spec.tsx
@@ -0,0 +1,117 @@
+import { render, screen, fireEvent } from '@testing-library/react';
+
+import MessageComposerInputExpandable from './MessageComposerInputExpandable';
+
+test('should show expand button when dimensions.blockSize > 100', () => {
+ render(
+ ,
+ );
+
+ const expandButton = screen.getByRole('button');
+ expect(expandButton).toBeInTheDocument();
+ expect(expandButton).toHaveAttribute('title', 'Expand');
+});
+
+test('should not show expand button when dimensions.blockSize <= 100', () => {
+ render(
+ ,
+ );
+
+ const expandButton = screen.queryByRole('button');
+ expect(expandButton).not.toBeInTheDocument();
+});
+
+test('should expand input when expand button is clicked', () => {
+ render(
+ ,
+ );
+
+ const expandButton = screen.getByRole('button');
+ const textarea = screen.getByRole('textbox');
+
+ // Initially not expanded
+ expect(textarea).not.toHaveStyle({ height: '500px' });
+
+ // Click to expand
+ fireEvent.click(expandButton);
+
+ // Should be expanded now
+ expect(textarea).toHaveStyle({ height: '500px' });
+ expect(textarea).toHaveStyle({ maxHeight: '50vh' });
+ expect(expandButton).toHaveAttribute('title', 'Collapse');
+});
+
+test('should collapse input when collapse button is clicked', () => {
+ render(
+ ,
+ );
+
+ const expandButton = screen.getByRole('button');
+ const textarea = screen.getByRole('textbox');
+
+ // Expand first
+ fireEvent.click(expandButton);
+ expect(textarea).toHaveStyle({ height: '500px' });
+
+ // Click to collapse
+ fireEvent.click(expandButton);
+
+ // Should be collapsed now
+ expect(textarea).not.toHaveStyle({ height: '500px' });
+ expect(textarea).not.toHaveStyle({ maxHeight: '50vh' });
+ expect(expandButton).toHaveAttribute('title', 'Expand');
+});
+
+test('should auto-collapse when input is cleared', () => {
+ render(
+ ,
+ );
+
+ const expandButton = screen.getByRole('button');
+ const textarea = screen.getByRole('textbox');
+
+ // Expand first
+ fireEvent.click(expandButton);
+ expect(textarea).toHaveStyle({ height: '500px' });
+
+ // Type some text
+ fireEvent.change(textarea, { target: { value: 'Some text' } });
+ expect(textarea).toHaveStyle({ height: '500px' });
+
+ // Clear the text
+ fireEvent.change(textarea, { target: { value: '' } });
+
+ // Should auto-collapse
+ expect(textarea).not.toHaveStyle({ height: '500px' });
+ expect(textarea).not.toHaveStyle({ maxHeight: '50vh' });
+});
diff --git a/packages/ui-composer/src/MessageComposer/MessageComposerInputExpandable.tsx b/packages/ui-composer/src/MessageComposer/MessageComposerInputExpandable.tsx
new file mode 100644
index 0000000000000..86ed216e699b3
--- /dev/null
+++ b/packages/ui-composer/src/MessageComposer/MessageComposerInputExpandable.tsx
@@ -0,0 +1,55 @@
+import { css } from '@rocket.chat/css-in-js';
+import { Box, IconButton } from '@rocket.chat/fuselage';
+import { useState, type ComponentProps, ChangeEvent, forwardRef } from 'react';
+import { useTranslation } from 'react-i18next';
+
+import MessageComposerInput from './MessageComposerInput';
+
+export type ExpandComposerButtonProps = ComponentProps & {
+ dimensions: Readonly<{
+ inlineSize: number;
+ blockSize: number;
+ }>;
+};
+
+const MessageComposerInputExpandable = forwardRef(
+ ({ dimensions, onChange, ...props }, ref) => {
+ const { t } = useTranslation();
+ const [expanded, setExpanded] = useState(false);
+
+ const handleChange = (event: ChangeEvent) => {
+ if (event.target.value.length === 0) {
+ setExpanded(false);
+ }
+
+ onChange?.(event);
+ };
+
+ return (
+ <>
+ {dimensions.blockSize > 100 && (
+
+ setExpanded(!expanded)}
+ />
+
+ )}
+
+ >
+ );
+ },
+);
+
+MessageComposerInputExpandable.displayName = 'MessageComposerInputExpandable';
+
+export default MessageComposerInputExpandable;
diff --git a/packages/ui-composer/src/MessageComposer/__snapshots__/MessageComposer.spec.tsx.snap b/packages/ui-composer/src/MessageComposer/__snapshots__/MessageComposer.spec.tsx.snap
index 4c69645109556..54d541276250d 100644
--- a/packages/ui-composer/src/MessageComposer/__snapshots__/MessageComposer.spec.tsx.snap
+++ b/packages/ui-composer/src/MessageComposer/__snapshots__/MessageComposer.spec.tsx.snap
@@ -189,6 +189,211 @@ exports[`renders Default without crashing 1`] = `
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/packages/ui-composer/src/MessageComposer/index.ts b/packages/ui-composer/src/MessageComposer/index.ts
index edf466ab2966f..1ff2874e90d16 100644
--- a/packages/ui-composer/src/MessageComposer/index.ts
+++ b/packages/ui-composer/src/MessageComposer/index.ts
@@ -5,6 +5,7 @@ import MessageComposerButton from './MessageComposerButton';
import MessageComposerHint from './MessageComposerHint';
import MessageComposerIcon from './MessageComposerIcon';
import MessageComposerInput from './MessageComposerInput';
+import MessageComposerInputExpandable from './MessageComposerInputExpandable';
import MessageComposerSkeleton from './MessageComposerSkeleton';
import MessageComposerToolbar from './MessageComposerToolbar';
import MessageComposerToolbarActions from './MessageComposerToolbarActions';
@@ -15,6 +16,7 @@ export {
MessageComposerAction,
MessageComposerActionsDivider,
MessageComposerInput,
+ MessageComposerInputExpandable,
MessageComposerToolbar,
MessageComposerToolbarActions,
MessageComposerToolbarSubmit,
diff --git a/packages/ui-voip/src/v2/useMediaSessionInstance.ts b/packages/ui-voip/src/v2/useMediaSessionInstance.ts
index db55bcfafb181..b72b250e97e4c 100644
--- a/packages/ui-voip/src/v2/useMediaSessionInstance.ts
+++ b/packages/ui-voip/src/v2/useMediaSessionInstance.ts
@@ -97,7 +97,8 @@ class MediaSessionStore extends Emitter<{ change: void }> {
private makeInstance(userId: string) {
if (this.sessionInstance !== null) {
- this.sessionInstance.disableStateReport();
+ this.sessionInstance.endSession();
+ this.sessionInstance = null;
}
if (!this._webrtcProcessorFactory || !this.sendSignalFn) {
diff --git a/packages/web-ui-registration/src/template/FormSkeleton.tsx b/packages/web-ui-registration/src/template/FormSkeleton.tsx
index 31425a0847f27..1fbe850d8abee 100644
--- a/packages/web-ui-registration/src/template/FormSkeleton.tsx
+++ b/packages/web-ui-registration/src/template/FormSkeleton.tsx
@@ -1,4 +1,4 @@
-import { Field, FieldLabel, FieldRow, FieldHint, FieldDescription, InputBox, Skeleton } from '@rocket.chat/fuselage';
+import { Field, FieldLabel, FieldRow, FieldHint, FieldDescription, Skeleton, InputBoxSkeleton } from '@rocket.chat/fuselage';
import { Form } from '@rocket.chat/layout';
import type { ReactElement } from 'react';
@@ -19,7 +19,7 @@ const FormSkeleton = (): ReactElement => {
-
+