Add autotranslations to permalink previews (#9540)
* Add autotranslations to permalink previews * Add missing change * Address feedback and fix test * Address feedback * Fix test * Revert "Fix test" This reverts commit 8aa88c33eb9f805ed57be5f0d90412c2657cca8f. * Revert "Address feedback" This reverts commit c0249d3d0b7a326f777234850e6519e0f98ef41c.
This commit is contained in:
parent
b4798e78cc
commit
058b87ee4d
5 changed files with 278 additions and 16 deletions
|
|
@ -136,6 +136,7 @@ describe('PermalinkPreview Enhanced Component', () => {
|
||||||
expect(permalinkPreview.props.author).toBeDefined();
|
expect(permalinkPreview.props.author).toBeDefined();
|
||||||
expect(permalinkPreview.props.currentUser).toBeDefined();
|
expect(permalinkPreview.props.currentUser).toBeDefined();
|
||||||
expect(permalinkPreview.props.isMilitaryTime).toBe(false);
|
expect(permalinkPreview.props.isMilitaryTime).toBe(false);
|
||||||
|
expect(permalinkPreview.props.autotranslationsEnabled).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -169,6 +170,7 @@ describe('PermalinkPreview Enhanced Component', () => {
|
||||||
expect(permalinkPreview.props.author).toBeUndefined();
|
expect(permalinkPreview.props.author).toBeUndefined();
|
||||||
expect(permalinkPreview.props.currentUser).toBeDefined();
|
expect(permalinkPreview.props.currentUser).toBeDefined();
|
||||||
expect(permalinkPreview.props.isMilitaryTime).toBe(false);
|
expect(permalinkPreview.props.isMilitaryTime).toBe(false);
|
||||||
|
expect(permalinkPreview.props.autotranslationsEnabled).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -209,6 +211,7 @@ describe('PermalinkPreview Enhanced Component', () => {
|
||||||
expect(permalinkPreview.props.teammateNameDisplay).toBe('username');
|
expect(permalinkPreview.props.teammateNameDisplay).toBe('username');
|
||||||
expect(permalinkPreview.props.currentUser).toBeDefined();
|
expect(permalinkPreview.props.currentUser).toBeDefined();
|
||||||
expect(permalinkPreview.props.isMilitaryTime).toBe(false);
|
expect(permalinkPreview.props.isMilitaryTime).toBe(false);
|
||||||
|
expect(permalinkPreview.props.autotranslationsEnabled).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -241,6 +244,7 @@ describe('PermalinkPreview Enhanced Component', () => {
|
||||||
expect(permalinkPreview.props.author).toBeUndefined();
|
expect(permalinkPreview.props.author).toBeUndefined();
|
||||||
expect(permalinkPreview.props.currentUser).toBeDefined();
|
expect(permalinkPreview.props.currentUser).toBeDefined();
|
||||||
expect(permalinkPreview.props.isMilitaryTime).toBe(false);
|
expect(permalinkPreview.props.isMilitaryTime).toBe(false);
|
||||||
|
expect(permalinkPreview.props.autotranslationsEnabled).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -281,6 +285,7 @@ describe('PermalinkPreview Enhanced Component', () => {
|
||||||
expect(permalinkPreview.props.teammateNameDisplay).toBe('full_name');
|
expect(permalinkPreview.props.teammateNameDisplay).toBe('full_name');
|
||||||
expect(permalinkPreview.props.currentUser).toBeDefined();
|
expect(permalinkPreview.props.currentUser).toBeDefined();
|
||||||
expect(permalinkPreview.props.isMilitaryTime).toBe(false);
|
expect(permalinkPreview.props.isMilitaryTime).toBe(false);
|
||||||
|
expect(permalinkPreview.props.autotranslationsEnabled).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -319,6 +324,58 @@ describe('PermalinkPreview Enhanced Component', () => {
|
||||||
await waitFor(() => {
|
await waitFor(() => {
|
||||||
const permalinkPreview = getByTestId('permalink-preview');
|
const permalinkPreview = getByTestId('permalink-preview');
|
||||||
expect(permalinkPreview.props.isMilitaryTime).toBe(true);
|
expect(permalinkPreview.props.isMilitaryTime).toBe(true);
|
||||||
|
expect(permalinkPreview.props.autotranslationsEnabled).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should pass autotranslationsEnabled true when channel has autotranslation enabled', async () => {
|
||||||
|
await operator.handleConfigs({
|
||||||
|
configs: [
|
||||||
|
{id: 'EnableAutoTranslation', value: 'true'},
|
||||||
|
{id: 'RestrictDMAndGMAutotranslation', value: 'false'},
|
||||||
|
],
|
||||||
|
configsToDelete: [],
|
||||||
|
prepareRecordsOnly: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
const channelId = 'channel-123';
|
||||||
|
const channel = TestHelper.fakeChannel({id: channelId, team_id: 'team1', autotranslation: true});
|
||||||
|
const myChannel = TestHelper.fakeMyChannel({
|
||||||
|
id: channelId,
|
||||||
|
channel_id: channelId,
|
||||||
|
user_id: 'current-user',
|
||||||
|
autotranslation_disabled: false,
|
||||||
|
});
|
||||||
|
await operator.handleChannel({channels: [channel], prepareRecordsOnly: false});
|
||||||
|
await operator.handleMyChannel({channels: [channel], myChannels: [myChannel], prepareRecordsOnly: false});
|
||||||
|
|
||||||
|
const embedData: PermalinkEmbedData = {
|
||||||
|
post_id: 'post-123',
|
||||||
|
post: TestHelper.fakePost({
|
||||||
|
id: 'post-123',
|
||||||
|
user_id: 'author-user',
|
||||||
|
message: 'Test message',
|
||||||
|
channel_id: channelId,
|
||||||
|
}),
|
||||||
|
team_name: 'test-team',
|
||||||
|
channel_display_name: 'Test Channel',
|
||||||
|
channel_type: 'O',
|
||||||
|
channel_id: channelId,
|
||||||
|
};
|
||||||
|
|
||||||
|
await createPostWithPermalinkEmbed(operator, database, embedData);
|
||||||
|
|
||||||
|
const {getByTestId} = renderWithEverything(
|
||||||
|
<EnhancedPermalinkPreview
|
||||||
|
embedData={embedData}
|
||||||
|
location={Screens.CHANNEL}
|
||||||
|
/>,
|
||||||
|
{database, serverUrl},
|
||||||
|
);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
const permalinkPreview = getByTestId('permalink-preview');
|
||||||
|
expect(permalinkPreview.props.autotranslationsEnabled).toBe(true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import {of as of$} from 'rxjs';
|
||||||
import {map, switchMap, distinctUntilChanged} from 'rxjs/operators';
|
import {map, switchMap, distinctUntilChanged} from 'rxjs/operators';
|
||||||
|
|
||||||
import {getDisplayNamePreferenceAsBool} from '@helpers/api/preference';
|
import {getDisplayNamePreferenceAsBool} from '@helpers/api/preference';
|
||||||
|
import {observeIsChannelAutotranslated} from '@queries/servers/channel';
|
||||||
import {observePost} from '@queries/servers/post';
|
import {observePost} from '@queries/servers/post';
|
||||||
import {queryDisplayNamePreferences} from '@queries/servers/preference';
|
import {queryDisplayNamePreferences} from '@queries/servers/preference';
|
||||||
import {observeUser, observeTeammateNameDisplay, observeCurrentUser} from '@queries/servers/user';
|
import {observeUser, observeTeammateNameDisplay, observeCurrentUser} from '@queries/servers/user';
|
||||||
|
|
@ -27,12 +28,17 @@ const enhance = withObservables(['embedData'], ({database, embedData}: WithDatab
|
||||||
const post = embedData?.post_id ? observePost(database, embedData.post_id) : of$(undefined);
|
const post = embedData?.post_id ? observePost(database, embedData.post_id) : of$(undefined);
|
||||||
const isOriginPostDeleted = post.pipe(
|
const isOriginPostDeleted = post.pipe(
|
||||||
switchMap((p) => {
|
switchMap((p) => {
|
||||||
const initialDeleted = Boolean(embedData?.post?.delete_at > 0 || embedData?.post?.state === 'DELETED');
|
const deleteAt = embedData?.post?.delete_at ?? 0;
|
||||||
|
const initialDeleted = Boolean(deleteAt > 0 || embedData?.post?.state === 'DELETED');
|
||||||
return of$(p ? p.deleteAt > 0 : initialDeleted);
|
return of$(p ? p.deleteAt > 0 : initialDeleted);
|
||||||
}),
|
}),
|
||||||
distinctUntilChanged(),
|
distinctUntilChanged(),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const channelId = embedData?.post?.channel_id;
|
||||||
|
|
||||||
|
const autotranslationsEnabled = channelId ? observeIsChannelAutotranslated(database, channelId) : of$(false);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
teammateNameDisplay,
|
teammateNameDisplay,
|
||||||
currentUser,
|
currentUser,
|
||||||
|
|
@ -40,6 +46,7 @@ const enhance = withObservables(['embedData'], ({database, embedData}: WithDatab
|
||||||
author,
|
author,
|
||||||
post,
|
post,
|
||||||
isOriginPostDeleted,
|
isOriginPostDeleted,
|
||||||
|
autotranslationsEnabled,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,11 @@
|
||||||
|
|
||||||
import {fireEvent} from '@testing-library/react-native';
|
import {fireEvent} from '@testing-library/react-native';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import {View} from 'react-native';
|
||||||
|
|
||||||
import {showPermalink} from '@actions/remote/permalink';
|
import {showPermalink} from '@actions/remote/permalink';
|
||||||
import Markdown from '@components/markdown';
|
import Markdown from '@components/markdown';
|
||||||
|
import TranslateIcon from '@components/post_list/post/header/translate_icon';
|
||||||
import {Screens} from '@constants';
|
import {Screens} from '@constants';
|
||||||
import DatabaseManager from '@database/manager';
|
import DatabaseManager from '@database/manager';
|
||||||
import {renderWithEverything} from '@test/intl-test-helper';
|
import {renderWithEverything} from '@test/intl-test-helper';
|
||||||
|
|
@ -28,6 +30,14 @@ jest.mocked(Markdown).mockImplementation((props) =>
|
||||||
React.createElement('Text', {testID: 'markdown'}, props.value),
|
React.createElement('Text', {testID: 'markdown'}, props.value),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
jest.mock('@components/post_list/post/header/translate_icon', () => ({
|
||||||
|
__esModule: true,
|
||||||
|
default: jest.fn(),
|
||||||
|
}));
|
||||||
|
jest.mocked(TranslateIcon).mockImplementation(() =>
|
||||||
|
React.createElement(View, {testID: 'translate-icon'}, null),
|
||||||
|
);
|
||||||
|
|
||||||
describe('components/post_list/post/body/content/permalink_preview/PermalinkPreview', () => {
|
describe('components/post_list/post/body/content/permalink_preview/PermalinkPreview', () => {
|
||||||
let database: Database;
|
let database: Database;
|
||||||
let operator: ServerDataOperator;
|
let operator: ServerDataOperator;
|
||||||
|
|
@ -81,7 +91,7 @@ describe('components/post_list/post/body/content/permalink_preview/PermalinkPrev
|
||||||
edit_at: 0,
|
edit_at: 0,
|
||||||
metadata: {
|
metadata: {
|
||||||
embeds: [{
|
embeds: [{
|
||||||
type: 'opengraph' as PostEmbedType,
|
type: 'opengraph',
|
||||||
url: 'https://example.com',
|
url: 'https://example.com',
|
||||||
data: {
|
data: {
|
||||||
title: 'Example Title',
|
title: 'Example Title',
|
||||||
|
|
@ -118,6 +128,7 @@ describe('components/post_list/post/body/content/permalink_preview/PermalinkPrev
|
||||||
isOriginPostDeleted: false,
|
isOriginPostDeleted: false,
|
||||||
parentLocation: Screens.CHANNEL,
|
parentLocation: Screens.CHANNEL,
|
||||||
parentPostId: 'parent-post-123',
|
parentPostId: 'parent-post-123',
|
||||||
|
autotranslationsEnabled: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
it('should render permalink preview correctly', () => {
|
it('should render permalink preview correctly', () => {
|
||||||
|
|
@ -141,7 +152,7 @@ describe('components/post_list/post/body/content/permalink_preview/PermalinkPrev
|
||||||
...baseProps,
|
...baseProps,
|
||||||
embedData: {
|
embedData: {
|
||||||
...baseProps.embedData,
|
...baseProps.embedData,
|
||||||
post: undefined as unknown as Post,
|
post: undefined,
|
||||||
},
|
},
|
||||||
post: undefined,
|
post: undefined,
|
||||||
};
|
};
|
||||||
|
|
@ -214,7 +225,7 @@ describe('components/post_list/post/body/content/permalink_preview/PermalinkPrev
|
||||||
message: 'Test message',
|
message: 'Test message',
|
||||||
metadata: {
|
metadata: {
|
||||||
embeds: [{
|
embeds: [{
|
||||||
type: 'opengraph' as PostEmbedType,
|
type: 'opengraph',
|
||||||
url: 'https://example.com',
|
url: 'https://example.com',
|
||||||
data: {
|
data: {
|
||||||
title: 'Example Title',
|
title: 'Example Title',
|
||||||
|
|
@ -262,7 +273,7 @@ describe('components/post_list/post/body/content/permalink_preview/PermalinkPrev
|
||||||
message: longMessage,
|
message: longMessage,
|
||||||
metadata: {
|
metadata: {
|
||||||
embeds: [{
|
embeds: [{
|
||||||
type: 'opengraph' as PostEmbedType,
|
type: 'opengraph',
|
||||||
url: 'https://example.com',
|
url: 'https://example.com',
|
||||||
data: {
|
data: {
|
||||||
title: 'Example Title',
|
title: 'Example Title',
|
||||||
|
|
@ -290,7 +301,7 @@ describe('components/post_list/post/body/content/permalink_preview/PermalinkPrev
|
||||||
message: '',
|
message: '',
|
||||||
metadata: {
|
metadata: {
|
||||||
embeds: [{
|
embeds: [{
|
||||||
type: 'opengraph' as PostEmbedType,
|
type: 'opengraph',
|
||||||
url: 'https://example.com',
|
url: 'https://example.com',
|
||||||
data: {
|
data: {
|
||||||
title: 'Example Title',
|
title: 'Example Title',
|
||||||
|
|
@ -319,7 +330,7 @@ describe('components/post_list/post/body/content/permalink_preview/PermalinkPrev
|
||||||
create_at: 1234567890000,
|
create_at: 1234567890000,
|
||||||
metadata: {
|
metadata: {
|
||||||
embeds: [{
|
embeds: [{
|
||||||
type: 'opengraph' as PostEmbedType,
|
type: 'opengraph',
|
||||||
url: 'https://example.com',
|
url: 'https://example.com',
|
||||||
data: {
|
data: {
|
||||||
title: 'Example Title',
|
title: 'Example Title',
|
||||||
|
|
@ -366,7 +377,7 @@ describe('components/post_list/post/body/content/permalink_preview/PermalinkPrev
|
||||||
metadata: {
|
metadata: {
|
||||||
files: [fileInfo],
|
files: [fileInfo],
|
||||||
embeds: [{
|
embeds: [{
|
||||||
type: 'opengraph' as PostEmbedType,
|
type: 'opengraph',
|
||||||
url: 'https://example.com',
|
url: 'https://example.com',
|
||||||
data: {
|
data: {
|
||||||
title: 'Example Title',
|
title: 'Example Title',
|
||||||
|
|
@ -412,7 +423,7 @@ describe('components/post_list/post/body/content/permalink_preview/PermalinkPrev
|
||||||
metadata: {
|
metadata: {
|
||||||
files: fileInfos,
|
files: fileInfos,
|
||||||
embeds: [{
|
embeds: [{
|
||||||
type: 'opengraph' as PostEmbedType,
|
type: 'opengraph',
|
||||||
url: 'https://example.com',
|
url: 'https://example.com',
|
||||||
data: {
|
data: {
|
||||||
title: 'Example Title',
|
title: 'Example Title',
|
||||||
|
|
@ -442,7 +453,7 @@ describe('components/post_list/post/body/content/permalink_preview/PermalinkPrev
|
||||||
message: 'Post without files',
|
message: 'Post without files',
|
||||||
metadata: {
|
metadata: {
|
||||||
embeds: [{
|
embeds: [{
|
||||||
type: 'opengraph' as PostEmbedType,
|
type: 'opengraph',
|
||||||
url: 'https://example.com',
|
url: 'https://example.com',
|
||||||
data: {
|
data: {
|
||||||
title: 'Example Title',
|
title: 'Example Title',
|
||||||
|
|
@ -473,7 +484,7 @@ describe('components/post_list/post/body/content/permalink_preview/PermalinkPrev
|
||||||
metadata: {
|
metadata: {
|
||||||
files: [],
|
files: [],
|
||||||
embeds: [{
|
embeds: [{
|
||||||
type: 'opengraph' as PostEmbedType,
|
type: 'opengraph',
|
||||||
url: 'https://example.com',
|
url: 'https://example.com',
|
||||||
data: {
|
data: {
|
||||||
title: 'Example Title',
|
title: 'Example Title',
|
||||||
|
|
@ -492,4 +503,175 @@ describe('components/post_list/post/body/content/permalink_preview/PermalinkPrev
|
||||||
expect(queryByTestId('permalink-files-container')).toBeNull();
|
expect(queryByTestId('permalink-files-container')).toBeNull();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('autotranslationsEnabled', () => {
|
||||||
|
it('should not render TranslateIcon when autotranslationsEnabled is false', () => {
|
||||||
|
const {queryByTestId} = renderPermalinkPreview({
|
||||||
|
...baseProps,
|
||||||
|
autotranslationsEnabled: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(queryByTestId('translate-icon')).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should render TranslateIcon when autotranslationsEnabled is true', () => {
|
||||||
|
const {getByTestId} = renderPermalinkPreview({
|
||||||
|
...baseProps,
|
||||||
|
autotranslationsEnabled: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getByTestId('translate-icon')).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display translated message when autotranslationsEnabled is true and translation is ready', () => {
|
||||||
|
const originalMessage = 'Original message';
|
||||||
|
const translatedMessage = 'Translated message';
|
||||||
|
const props = {
|
||||||
|
...baseProps,
|
||||||
|
autotranslationsEnabled: true,
|
||||||
|
embedData: {
|
||||||
|
...baseProps.embedData,
|
||||||
|
post: TestHelper.fakePost({
|
||||||
|
id: 'post-123',
|
||||||
|
user_id: 'user-123',
|
||||||
|
message: originalMessage,
|
||||||
|
create_at: 1234567890000,
|
||||||
|
edit_at: 0,
|
||||||
|
metadata: {
|
||||||
|
translations: {
|
||||||
|
en: {
|
||||||
|
state: 'ready',
|
||||||
|
object: {message: translatedMessage},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
embeds: [{
|
||||||
|
type: 'opengraph',
|
||||||
|
url: 'https://example.com',
|
||||||
|
data: {
|
||||||
|
title: 'Example Title',
|
||||||
|
description: 'Example Description',
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const {getByText} = renderPermalinkPreview(props);
|
||||||
|
|
||||||
|
expect(getByText(translatedMessage)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display original message when autotranslationsEnabled is true but translation is not ready', () => {
|
||||||
|
const originalMessage = 'Original message only';
|
||||||
|
const props = {
|
||||||
|
...baseProps,
|
||||||
|
autotranslationsEnabled: true,
|
||||||
|
embedData: {
|
||||||
|
...baseProps.embedData,
|
||||||
|
post: TestHelper.fakePost({
|
||||||
|
id: 'post-123',
|
||||||
|
user_id: 'user-123',
|
||||||
|
message: originalMessage,
|
||||||
|
create_at: 1234567890000,
|
||||||
|
edit_at: 0,
|
||||||
|
metadata: {
|
||||||
|
translations: {
|
||||||
|
en: {
|
||||||
|
state: 'processing',
|
||||||
|
object: {message: ''},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
embeds: [{
|
||||||
|
type: 'opengraph',
|
||||||
|
url: 'https://example.com',
|
||||||
|
data: {
|
||||||
|
title: 'Example Title',
|
||||||
|
description: 'Example Description',
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const {getByText} = renderPermalinkPreview(props);
|
||||||
|
|
||||||
|
expect(getByText(originalMessage)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display original message when autotranslationsEnabled is false regardless of translation', () => {
|
||||||
|
const originalMessage = 'Original message';
|
||||||
|
const props = {
|
||||||
|
...baseProps,
|
||||||
|
autotranslationsEnabled: false,
|
||||||
|
embedData: {
|
||||||
|
...baseProps.embedData,
|
||||||
|
post: TestHelper.fakePost({
|
||||||
|
id: 'post-123',
|
||||||
|
user_id: 'user-123',
|
||||||
|
message: originalMessage,
|
||||||
|
create_at: 1234567890000,
|
||||||
|
edit_at: 0,
|
||||||
|
metadata: {
|
||||||
|
translations: {
|
||||||
|
en: {
|
||||||
|
state: 'ready',
|
||||||
|
object: {message: 'Translated message'},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
embeds: [{
|
||||||
|
type: 'opengraph',
|
||||||
|
url: 'https://example.com',
|
||||||
|
data: {
|
||||||
|
title: 'Example Title',
|
||||||
|
description: 'Example Description',
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const {getByText} = renderPermalinkPreview(props);
|
||||||
|
|
||||||
|
expect(getByText(originalMessage)).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not translate custom posts or show TranslateIcon when autotranslationsEnabled is true', () => {
|
||||||
|
const originalMessage = 'Custom message';
|
||||||
|
const translatedMessage = 'Translated custom message';
|
||||||
|
const props = {
|
||||||
|
...baseProps,
|
||||||
|
autotranslationsEnabled: true,
|
||||||
|
embedData: {
|
||||||
|
...baseProps.embedData,
|
||||||
|
post: TestHelper.fakePost({
|
||||||
|
id: 'system-post-123',
|
||||||
|
user_id: 'user-123',
|
||||||
|
type: 'custom_llmbot',
|
||||||
|
message: originalMessage,
|
||||||
|
create_at: 1234567890000,
|
||||||
|
edit_at: 0,
|
||||||
|
metadata: {
|
||||||
|
translations: {
|
||||||
|
en: {
|
||||||
|
state: 'ready',
|
||||||
|
object: {message: translatedMessage},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
embeds: [{
|
||||||
|
type: 'opengraph',
|
||||||
|
url: 'https://example.com',
|
||||||
|
data: {
|
||||||
|
title: 'Example Title',
|
||||||
|
description: 'Example Description',
|
||||||
|
},
|
||||||
|
}],
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const {queryByTestId, getByText} = renderPermalinkPreview(props);
|
||||||
|
expect(queryByTestId('translate-icon')).toBeNull();
|
||||||
|
expect(getByText(originalMessage)).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ import EditedIndicator from '@components/edited_indicator';
|
||||||
import FormattedText from '@components/formatted_text';
|
import FormattedText from '@components/formatted_text';
|
||||||
import FormattedTime from '@components/formatted_time';
|
import FormattedTime from '@components/formatted_time';
|
||||||
import Markdown from '@components/markdown';
|
import Markdown from '@components/markdown';
|
||||||
|
import TranslateIcon from '@components/post_list/post/header/translate_icon';
|
||||||
import ProfilePicture from '@components/profile_picture';
|
import ProfilePicture from '@components/profile_picture';
|
||||||
import {View as ViewConstants} from '@constants';
|
import {View as ViewConstants} from '@constants';
|
||||||
import {useServerUrl} from '@context/server';
|
import {useServerUrl} from '@context/server';
|
||||||
|
|
@ -18,6 +19,7 @@ import {useTheme} from '@context/theme';
|
||||||
import {useUserLocale} from '@context/user_locale';
|
import {useUserLocale} from '@context/user_locale';
|
||||||
import {useIsTablet, useWindowDimensions} from '@hooks/device';
|
import {useIsTablet, useWindowDimensions} from '@hooks/device';
|
||||||
import {usePreventDoubleTap} from '@hooks/utils';
|
import {usePreventDoubleTap} from '@hooks/utils';
|
||||||
|
import {getPostTranslatedMessage, getPostTranslation} from '@utils/post';
|
||||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||||
import {typography} from '@utils/typography';
|
import {typography} from '@utils/typography';
|
||||||
import {displayUsername, getUserTimezone} from '@utils/user';
|
import {displayUsername, getUserTimezone} from '@utils/user';
|
||||||
|
|
@ -46,6 +48,7 @@ type PermalinkPreviewProps = {
|
||||||
location: AvailableScreens;
|
location: AvailableScreens;
|
||||||
parentLocation?: string;
|
parentLocation?: string;
|
||||||
parentPostId?: string;
|
parentPostId?: string;
|
||||||
|
autotranslationsEnabled: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||||
|
|
@ -77,6 +80,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||||
marginLeft: 12,
|
marginLeft: 12,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
gap: 8,
|
||||||
},
|
},
|
||||||
authorName: {
|
authorName: {
|
||||||
color: theme.centerChannelColor,
|
color: theme.centerChannelColor,
|
||||||
|
|
@ -85,7 +89,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
||||||
timestamp: {
|
timestamp: {
|
||||||
color: changeOpacity(theme.centerChannelColor, 0.64),
|
color: changeOpacity(theme.centerChannelColor, 0.64),
|
||||||
...typography('Body', 75),
|
...typography('Body', 75),
|
||||||
marginLeft: 8,
|
|
||||||
},
|
},
|
||||||
messageContainer: {
|
messageContainer: {
|
||||||
marginBottom: 8,
|
marginBottom: 8,
|
||||||
|
|
@ -130,6 +133,7 @@ const PermalinkPreview = ({
|
||||||
location,
|
location,
|
||||||
parentLocation,
|
parentLocation,
|
||||||
parentPostId,
|
parentPostId,
|
||||||
|
autotranslationsEnabled,
|
||||||
}: PermalinkPreviewProps) => {
|
}: PermalinkPreviewProps) => {
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
const serverUrl = useServerUrl();
|
const serverUrl = useServerUrl();
|
||||||
|
|
@ -170,8 +174,15 @@ const PermalinkPreview = ({
|
||||||
channel_type,
|
channel_type,
|
||||||
} = embedData;
|
} = embedData;
|
||||||
|
|
||||||
|
const translation = embedPost ? getPostTranslation(embedPost, locale) : undefined;
|
||||||
|
|
||||||
const truncatedMessage = useMemo(() => {
|
const truncatedMessage = useMemo(() => {
|
||||||
const msg = embedPost?.message;
|
let msg = embedPost?.message ?? '';
|
||||||
|
if (autotranslationsEnabled && embedPost?.type === '') {
|
||||||
|
if (translation?.state === 'ready') {
|
||||||
|
msg = getPostTranslatedMessage(msg, translation);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!msg || typeof msg !== 'string') {
|
if (!msg || typeof msg !== 'string') {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
@ -183,7 +194,7 @@ const PermalinkPreview = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
return cleanMessage;
|
return cleanMessage;
|
||||||
}, [embedPost?.message]);
|
}, [autotranslationsEnabled, embedPost?.message, embedPost?.type, translation]);
|
||||||
|
|
||||||
const isEdited = useMemo(() => embedData && embedData.post && embedData.post.edit_at > 0, [embedData]);
|
const isEdited = useMemo(() => embedData && embedData.post && embedData.post.edit_at > 0, [embedData]);
|
||||||
|
|
||||||
|
|
@ -254,9 +265,14 @@ const PermalinkPreview = ({
|
||||||
<FormattedTime
|
<FormattedTime
|
||||||
timezone={getUserTimezone(currentUser)}
|
timezone={getUserTimezone(currentUser)}
|
||||||
isMilitaryTime={isMilitaryTime}
|
isMilitaryTime={isMilitaryTime}
|
||||||
value={embedPost.create_at}
|
value={embedPost?.create_at ?? 0}
|
||||||
style={styles.timestamp}
|
style={styles.timestamp}
|
||||||
/>
|
/>
|
||||||
|
{autotranslationsEnabled && embedPost?.type === '' && (
|
||||||
|
<TranslateIcon
|
||||||
|
translationState={translation?.state}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
|
|
||||||
2
types/api/posts.d.ts
vendored
2
types/api/posts.d.ts
vendored
|
|
@ -51,7 +51,7 @@ type PostPriority = {
|
||||||
|
|
||||||
type PermalinkEmbedData = {
|
type PermalinkEmbedData = {
|
||||||
post_id: string;
|
post_id: string;
|
||||||
post: Post;
|
post?: Post;
|
||||||
team_name: string;
|
team_name: string;
|
||||||
channel_display_name: string;
|
channel_display_name: string;
|
||||||
channel_type: string;
|
channel_type: string;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue