Merge branch 'develop' into fix.link-preview

This commit is contained in:
Reinaldo Neto 2022-12-06 11:54:05 -03:00 committed by GitHub
commit 87d0b6173c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 67 additions and 28 deletions

View File

@ -147,7 +147,7 @@ android {
minSdkVersion rootProject.ext.minSdkVersion minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion
versionCode VERSIONCODE as Integer versionCode VERSIONCODE as Integer
versionName "4.33.0" versionName "4.34.0"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
if (!isFoss) { if (!isFoss) {
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String] manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]

View File

@ -565,6 +565,8 @@
"Unsupported_system_message": "Unsupported system message", "Unsupported_system_message": "Unsupported system message",
"Updating": "Updating...", "Updating": "Updating...",
"Uploading": "Uploading", "Uploading": "Uploading",
"FileUpload_Error": "File Upload Error",
"Upload_in_progress": "Upload in progress",
"Upload_file_question_mark": "Upload file?", "Upload_file_question_mark": "Upload file?",
"User": "User", "User": "User",
"Users": "Users", "Users": "Users",

View File

@ -513,6 +513,8 @@
"Unsupported_system_message": "Mensagem de sistema não suportada", "Unsupported_system_message": "Mensagem de sistema não suportada",
"Updating": "Atualizando...", "Updating": "Atualizando...",
"Uploading": "Subindo arquivo", "Uploading": "Subindo arquivo",
"FileUpload_Error": "Erro de upload de arquivo",
"Upload_in_progress": "Carregamento em andamento",
"Upload_file_question_mark": "Enviar arquivo?", "Upload_file_question_mark": "Enviar arquivo?",
"User": "Usuário", "User": "Usuário",
"Users": "Usuários", "Users": "Usuários",

View File

@ -1,27 +1,35 @@
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord'; import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
import { settings as RocketChatSettings } from '@rocket.chat/sdk'; import { settings as RocketChatSettings } from '@rocket.chat/sdk';
import { FetchBlobResponse, StatefulPromise } from 'rn-fetch-blob';
import isEmpty from 'lodash/isEmpty'; import isEmpty from 'lodash/isEmpty';
import { FetchBlobResponse, StatefulPromise } from 'rn-fetch-blob';
import { Alert } from 'react-native';
import FileUpload from './helpers/fileUpload';
import database from '../database';
import log from './helpers/log';
import { IUpload, IUser, TUploadModel } from '../../definitions'; import { IUpload, IUser, TUploadModel } from '../../definitions';
import i18n from '../../i18n';
import database from '../database';
import FileUpload from './helpers/fileUpload';
import { IFileUpload } from './helpers/fileUpload/interfaces'; import { IFileUpload } from './helpers/fileUpload/interfaces';
import log from './helpers/log';
const uploadQueue: { [index: string]: StatefulPromise<FetchBlobResponse> } = {}; const uploadQueue: { [index: string]: StatefulPromise<FetchBlobResponse> } = {};
export function isUploadActive(path: string): boolean { const getUploadPath = (path: string, rid: string) => `${path}-${rid}`;
return !!uploadQueue[path];
export function isUploadActive(path: string, rid: string): boolean {
return !!uploadQueue[getUploadPath(path, rid)];
} }
export async function cancelUpload(item: TUploadModel): Promise<void> { export async function cancelUpload(item: TUploadModel, rid: string): Promise<void> {
if (!isEmpty(uploadQueue[item.path])) { const uploadPath = getUploadPath(item.path, rid);
if (!isEmpty(uploadQueue[uploadPath])) {
try { try {
await uploadQueue[item.path].cancel(); await uploadQueue[uploadPath].cancel();
} catch { } catch {
// Do nothing // Do nothing
} }
delete uploadQueue[uploadPath];
}
if (item.id) {
try { try {
const db = database.active; const db = database.active;
await db.write(async () => { await db.write(async () => {
@ -30,7 +38,6 @@ export async function cancelUpload(item: TUploadModel): Promise<void> {
} catch (e) { } catch (e) {
log(e); log(e);
} }
delete uploadQueue[item.path];
} }
} }
@ -51,14 +58,18 @@ export function sendFileMessage(
const db = database.active; const db = database.active;
const uploadsCollection = db.get('uploads'); const uploadsCollection = db.get('uploads');
const uploadPath = getUploadPath(fileInfo.path, rid);
let uploadRecord: TUploadModel; let uploadRecord: TUploadModel;
try { try {
uploadRecord = await uploadsCollection.find(fileInfo.path); uploadRecord = await uploadsCollection.find(uploadPath);
if (uploadRecord.id) {
return Alert.alert(i18n.t('FileUpload_Error'), i18n.t('Upload_in_progress'));
}
} catch (error) { } catch (error) {
try { try {
await db.write(async () => { await db.write(async () => {
uploadRecord = await uploadsCollection.create(u => { uploadRecord = await uploadsCollection.create(u => {
u._raw = sanitizedRaw({ id: fileInfo.path }, uploadsCollection.schema); u._raw = sanitizedRaw({ id: uploadPath }, uploadsCollection.schema);
Object.assign(u, fileInfo); Object.assign(u, fileInfo);
if (u.subscription) { if (u.subscription) {
u.subscription.id = rid; u.subscription.id = rid;
@ -99,9 +110,9 @@ export function sendFileMessage(
'X-User-Id': id 'X-User-Id': id
}; };
uploadQueue[fileInfo.path] = FileUpload.fetch('POST', uploadUrl, headers, formData); uploadQueue[uploadPath] = FileUpload.fetch('POST', uploadUrl, headers, formData);
uploadQueue[fileInfo.path].uploadProgress(async (loaded: number, total: number) => { uploadQueue[uploadPath].uploadProgress(async (loaded: number, total: number) => {
try { try {
await db.write(async () => { await db.write(async () => {
await uploadRecord.update(u => { await uploadRecord.update(u => {
@ -113,7 +124,7 @@ export function sendFileMessage(
} }
}); });
uploadQueue[fileInfo.path].then(async response => { uploadQueue[uploadPath].then(async response => {
if (response.respInfo.status >= 200 && response.respInfo.status < 400) { if (response.respInfo.status >= 200 && response.respInfo.status < 400) {
// If response is all good... // If response is all good...
try { try {
@ -142,7 +153,7 @@ export function sendFileMessage(
} }
}); });
uploadQueue[fileInfo.path].catch(async error => { uploadQueue[uploadPath].catch(async error => {
try { try {
await db.write(async () => { await db.write(async () => {
await uploadRecord.update(u => { await uploadRecord.update(u => {

View File

@ -112,9 +112,10 @@ class UploadProgress extends Component<IUploadProgressProps, IUploadProgressStat
uploadCheck = () => { uploadCheck = () => {
this.ranInitialUploadCheck = true; this.ranInitialUploadCheck = true;
const { rid } = this.props;
const { uploads } = this.state; const { uploads } = this.state;
uploads.forEach(async u => { uploads.forEach(async u => {
if (!isUploadActive(u.path)) { if (!isUploadActive(u.path, rid)) {
try { try {
const db = database.active; const db = database.active;
await db.write(async () => { await db.write(async () => {
@ -141,8 +142,9 @@ class UploadProgress extends Component<IUploadProgressProps, IUploadProgressStat
}; };
handleCancelUpload = async (item: TUploadModel) => { handleCancelUpload = async (item: TUploadModel) => {
const { rid } = this.props;
try { try {
await cancelUpload(item); await cancelUpload(item, rid);
} catch (e) { } catch (e) {
log(e); log(e);
} }
@ -210,7 +212,7 @@ class UploadProgress extends Component<IUploadProgressProps, IUploadProgressStat
key={item.path} key={item.path}
style={[ style={[
styles.item, styles.item,
index !== 0 ? { marginTop: 10 } : {}, index !== 0 ? { marginTop: 4 } : {},
{ {
backgroundColor: themes[theme!].chatComponentBackground, backgroundColor: themes[theme!].chatComponentBackground,
borderColor: themes[theme!].borderColor borderColor: themes[theme!].borderColor

View File

@ -142,7 +142,7 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
), ),
headerRight: () => ( headerRight: () => (
<HeaderButton.Container> <HeaderButton.Container>
<HeaderButton.Item iconName='search' onPress={this.onSearchPress} /> <HeaderButton.Item iconName='search' onPress={this.onSearchPress} testID='thread-messages-view-search-icon' />
</HeaderButton.Container> </HeaderButton.Container>
) )
}; };
@ -242,7 +242,7 @@ class ThreadMessagesView extends React.Component<IThreadMessagesViewProps, IThre
const { subscription } = this.state; const { subscription } = this.state;
// if there's no subscription, manage data on this.state.messages // if there's no subscription, manage data on this.state.messages
// note: sync will never be called without subscription // note: sync will never be called without subscription
if (!subscription) { if (!subscription._id) {
this.setState(({ messages }) => ({ messages: [...messages, ...update] })); this.setState(({ messages }) => ({ messages: [...messages, ...update] }));
return; return;
} }

View File

@ -1,5 +1,6 @@
import data from '../../data'; import data from '../../data';
import { navigateToLogin, login, tapBack, sleep } from '../../helpers/app'; import { navigateToLogin, login, tapBack, sleep } from '../../helpers/app';
import { sendMessage } from '../../helpers/data_setup';
const testuser = data.users.regular; const testuser = data.users.regular;
@ -26,6 +27,13 @@ describe('Join room from directory', () => {
}); });
describe('Usage', () => { describe('Usage', () => {
const threadMessage = `thread-${data.random}`;
before(async () => {
const result = await sendMessage(data.users.alternate, data.channels.detoxpublic.name, threadMessage);
const threadId = result.message._id;
await sendMessage(data.users.alternate, result.message.rid, data.random, threadId);
});
it('should tap directory', async () => { it('should tap directory', async () => {
await element(by.id('rooms-list-view-directory')).tap(); await element(by.id('rooms-list-view-directory')).tap();
await waitFor(element(by.id('directory-view'))) await waitFor(element(by.id('directory-view')))
@ -37,6 +45,20 @@ describe('Join room from directory', () => {
await navigateToRoom(data.channels.detoxpublic.name); await navigateToRoom(data.channels.detoxpublic.name);
}); });
it('should navigate to thread messages view and load messages', async () => {
await waitFor(element(by.id('room-view-header-threads')))
.toBeVisible()
.withTimeout(2000);
await element(by.id('room-view-header-threads')).tap();
await waitFor(element(by.id(`thread-messages-view-${threadMessage}`)))
.toBeVisible()
.withTimeout(2000);
await tapBack();
await waitFor(element(by.id('room-view-header-threads')))
.toBeVisible()
.withTimeout(2000);
});
it('should search user and navigate', async () => { it('should search user and navigate', async () => {
await tapBack(); await tapBack();
await element(by.id('rooms-list-view-directory')).tap(); await element(by.id('rooms-list-view-directory')).tap();

View File

@ -1767,7 +1767,7 @@
INFOPLIST_FILE = NotificationService/Info.plist; INFOPLIST_FILE = NotificationService/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 4.33.0; MARKETING_VERSION = 4.34.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
@ -1806,7 +1806,7 @@
INFOPLIST_FILE = NotificationService/Info.plist; INFOPLIST_FILE = NotificationService/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 12.0; IPHONEOS_DEPLOYMENT_TARGET = 12.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MARKETING_VERSION = 4.33.0; MARKETING_VERSION = 4.34.0;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
PRODUCT_BUNDLE_IDENTIFIER = chat.rocket.reactnative.NotificationService; PRODUCT_BUNDLE_IDENTIFIER = chat.rocket.reactnative.NotificationService;

View File

@ -26,7 +26,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>4.33.0</string> <string>4.34.0</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>

View File

@ -26,7 +26,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>XPC!</string> <string>XPC!</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>4.33.0</string> <string>4.34.0</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1</string> <string>1</string>
<key>KeychainGroup</key> <key>KeychainGroup</key>

View File

@ -1,6 +1,6 @@
{ {
"name": "rocket-chat-reactnative", "name": "rocket-chat-reactnative",
"version": "4.33.0", "version": "4.34.0",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "react-native start", "start": "react-native start",

View File

@ -17379,7 +17379,7 @@ react-native-text-size@4.0.0-rc.1:
react-native-ui-lib@RocketChat/react-native-ui-lib: react-native-ui-lib@RocketChat/react-native-ui-lib:
version "4.2.0" version "4.2.0"
resolved "https://codeload.github.com/RocketChat/react-native-ui-lib/tar.gz/d20c1bcd09b694fc5133fc2232fd510f5f4ba581" resolved "https://codeload.github.com/RocketChat/react-native-ui-lib/tar.gz/fd5869e493b5b9cf888cec4a252c9ef292364b02"
dependencies: dependencies:
babel-plugin-transform-inline-environment-variables "^0.0.2" babel-plugin-transform-inline-environment-variables "^0.0.2"
color "^3.1.0" color "^3.1.0"