Merge branch 'develop' into chore/unused-imports

This commit is contained in:
Diego Mello 2021-10-06 18:11:32 -03:00 committed by GitHub
commit f11bbb814f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
80 changed files with 11445 additions and 4756 deletions

File diff suppressed because it is too large Load Diff

View File

@ -144,7 +144,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.20.0" versionName "4.21.0"
vectorDrawables.useSupportLibrary = true vectorDrawables.useSupportLibrary = true
if (!isFoss) { if (!isFoss) {
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String] manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
@ -260,7 +260,6 @@ android {
dependencies { dependencies {
addUnimodulesDependencies() addUnimodulesDependencies()
implementation project(':watermelondb')
implementation project(':@react-native-community_viewpager') implementation project(':@react-native-community_viewpager')
playImplementation project(':reactnativenotifications') playImplementation project(':reactnativenotifications')
playImplementation project(':@react-native-firebase_app') playImplementation project(':@react-native-firebase_app')
@ -293,6 +292,8 @@ dependencies {
implementation "com.github.bumptech.glide:glide:4.9.0" implementation "com.github.bumptech.glide:glide:4.9.0"
annotationProcessor "com.github.bumptech.glide:compiler:4.9.0" annotationProcessor "com.github.bumptech.glide:compiler:4.9.0"
implementation "com.tencent:mmkv-static:1.2.1" implementation "com.tencent:mmkv-static:1.2.1"
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
implementation "com.squareup.okhttp3:okhttp-urlconnection:4.9.0"
} }
// Run this once to be able to run the application with BUCK // Run this once to be able to run the application with BUCK

View File

@ -3,7 +3,6 @@
package="chat.rocket.reactnative"> package="chat.rocket.reactnative">
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application <application

View File

@ -9,8 +9,9 @@ import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage; import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader; import com.facebook.soloader.SoLoader;
import com.nozbe.watermelondb.WatermelonDBPackage;
import com.reactnativecommunity.viewpager.RNCViewPagerPackage; import com.reactnativecommunity.viewpager.RNCViewPagerPackage;
import com.facebook.react.bridge.JSIModulePackage;
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
import org.unimodules.adapters.react.ModuleRegistryAdapter; import org.unimodules.adapters.react.ModuleRegistryAdapter;
import org.unimodules.adapters.react.ReactModuleRegistryProvider; import org.unimodules.adapters.react.ReactModuleRegistryProvider;
@ -35,7 +36,6 @@ public class MainApplication extends Application implements ReactApplication {
protected List<ReactPackage> getPackages() { protected List<ReactPackage> getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable") @SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages(); List<ReactPackage> packages = new PackageList(this).getPackages();
packages.add(new WatermelonDBPackage());
packages.add(new RNCViewPagerPackage()); packages.add(new RNCViewPagerPackage());
packages.add(new SSLPinningPackage()); packages.add(new SSLPinningPackage());
List<ReactPackage> unimodules = Arrays.<ReactPackage>asList( List<ReactPackage> unimodules = Arrays.<ReactPackage>asList(
@ -52,6 +52,11 @@ public class MainApplication extends Application implements ReactApplication {
return "index"; return "index";
} }
@Override
protected JSIModulePackage getJSIModulePackage() {
return new ReanimatedJSIModulePackage(); // <- add
}
@Override @Override
protected @Nullable String getBundleAssetName() { protected @Nullable String getBundleAssetName() {
return "app.bundle"; return "app.bundle";

View File

@ -10,8 +10,8 @@ buildscript {
ext { ext {
buildToolsVersion = "29.0.3" buildToolsVersion = "29.0.3"
minSdkVersion = 23 minSdkVersion = 23
compileSdkVersion = 29 compileSdkVersion = 30
targetSdkVersion = 29 targetSdkVersion = 30
ndkVersion = "20.1.5948944" ndkVersion = "20.1.5948944"
glideVersion = "4.11.0" glideVersion = "4.11.0"
kotlin_version = "1.3.50" kotlin_version = "1.3.50"
@ -68,10 +68,10 @@ subprojects { subproject ->
afterEvaluate { afterEvaluate {
if ((subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) { if ((subproject.plugins.hasPlugin('android') || subproject.plugins.hasPlugin('android-library'))) {
android { android {
compileSdkVersion 29 compileSdkVersion 30
buildToolsVersion "29.0.3" buildToolsVersion "29.0.3"
defaultConfig { defaultConfig {
targetSdkVersion 29 targetSdkVersion 30
} }
variantFilter { variant -> variantFilter { variant ->
def names = variant.flavors*.name def names = variant.flavors*.name

View File

@ -2,8 +2,6 @@ apply from: '../node_modules/react-native-unimodules/gradle.groovy'
includeUnimodulesProjects() includeUnimodulesProjects()
rootProject.name = 'RocketChatRN' rootProject.name = 'RocketChatRN'
include ':watermelondb'
project(':watermelondb').projectDir = new File(rootProject.projectDir, '../node_modules/@nozbe/watermelondb/native/android')
include ':reactnativenotifications' include ':reactnativenotifications'
project(':reactnativenotifications').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-notifications/android/app') project(':reactnativenotifications').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-notifications/android/app')
include ':@react-native-community_viewpager' include ':@react-native-community_viewpager'

View File

@ -18,8 +18,6 @@ export const ROOMS = createRequestTypes('ROOMS', [
'SET_SEARCH', 'SET_SEARCH',
'CLOSE_SERVER_DROPDOWN', 'CLOSE_SERVER_DROPDOWN',
'TOGGLE_SERVER_DROPDOWN', 'TOGGLE_SERVER_DROPDOWN',
'CLOSE_SORT_DROPDOWN',
'TOGGLE_SORT_DROPDOWN',
'OPEN_SEARCH_HEADER', 'OPEN_SEARCH_HEADER',
'CLOSE_SEARCH_HEADER' 'CLOSE_SEARCH_HEADER'
]); ]);

View File

@ -45,18 +45,6 @@ export function toggleServerDropdown() {
}; };
} }
export function closeSortDropdown() {
return {
type: types.ROOMS.CLOSE_SORT_DROPDOWN
};
}
export function toggleSortDropdown() {
return {
type: types.ROOMS.TOGGLE_SORT_DROPDOWN
};
}
export function openSearchHeader() { export function openSearchHeader() {
return { return {
type: types.ROOMS.OPEN_SEARCH_HEADER type: types.ROOMS.OPEN_SEARCH_HEADER

View File

@ -0,0 +1,2 @@
export const DISPLAY_MODE_CONDENSED = 'condensed';
export const DISPLAY_MODE_EXPANDED = 'expanded';

View File

@ -3,7 +3,7 @@ import { Keyboard, Text } from 'react-native';
import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { useSafeAreaInsets } from 'react-native-safe-area-context';
import { State, TapGestureHandler } from 'react-native-gesture-handler'; import { State, TapGestureHandler } from 'react-native-gesture-handler';
import ScrollBottomSheet from 'react-native-scroll-bottom-sheet'; import ScrollBottomSheet from 'react-native-scroll-bottom-sheet';
import Animated, { Easing, Extrapolate, Value, interpolate } from 'react-native-reanimated'; import Animated, { Easing, Extrapolate, Value, interpolateNode } from 'react-native-reanimated';
import * as Haptics from 'expo-haptics'; import * as Haptics from 'expo-haptics';
import { useBackHandler } from '@react-native-community/hooks'; import { useBackHandler } from '@react-native-community/hooks';
@ -132,11 +132,12 @@ const ActionSheet = React.memo(
const renderItem = ({ item }: any) => <Item item={item} hide={hide} theme={theme} />; const renderItem = ({ item }: any) => <Item item={item} hide={hide} theme={theme} />;
const animatedPosition = React.useRef(new Value(0)); const animatedPosition = React.useRef(new Value(0));
const opacity = interpolate(animatedPosition.current, { // TODO: Similar to https://github.com/wcandillon/react-native-redash/issues/307#issuecomment-827442320
const opacity = interpolateNode(animatedPosition.current, {
inputRange: [0, 1], inputRange: [0, 1],
outputRange: [0, themes[theme].backdropOpacity], outputRange: [0, themes[theme].backdropOpacity],
extrapolate: Extrapolate.CLAMP extrapolate: Extrapolate.CLAMP
}); }) as any;
return ( return (
<> <>

View File

@ -85,7 +85,7 @@ const Avatar = React.memo(
} }
return ( return (
<View style={[avatarStyle, style]}> <View style={[avatarStyle, style]} testID='avatar'>
{image} {image}
{children} {children}
</View> </View>

View File

@ -22,11 +22,11 @@ const styles = StyleSheet.create({
} }
}); });
export const FormContainerInner = ({ children }: { children: JSX.Element }) => ( export const FormContainerInner = ({ children }: { children: React.ReactNode }): JSX.Element => (
<View style={[sharedStyles.container, isTablet && sharedStyles.tabletScreenContent]}>{children}</View> <View style={[sharedStyles.container, isTablet && sharedStyles.tabletScreenContent]}>{children}</View>
); );
const FormContainer = ({ children, theme, testID, ...props }: IFormContainer) => ( const FormContainer = ({ children, theme, testID, ...props }: IFormContainer): JSX.Element => (
// @ts-ignore // @ts-ignore
<KeyboardView <KeyboardView
style={{ backgroundColor: themes[theme].backgroundColor }} style={{ backgroundColor: themes[theme].backgroundColor }}

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { StyleSheet, Text, View } from 'react-native'; import { StyleSheet, Text, View } from 'react-native';
import { BorderlessButton } from 'react-native-gesture-handler'; import Touchable from 'react-native-platform-touchable';
import sharedStyles from '../views/Styles'; import sharedStyles from '../views/Styles';
import TextInput from '../presentation/TextInput'; import TextInput from '../presentation/TextInput';
@ -95,9 +95,9 @@ export default class RCTextInput extends React.PureComponent<IRCTextInputProps,
get iconRight() { get iconRight() {
const { iconRight, onIconRightPress, theme } = this.props; const { iconRight, onIconRightPress, theme } = this.props;
return ( return (
<BorderlessButton onPress={onIconRightPress} style={[styles.iconContainer, styles.iconRight]}> <Touchable onPress={onIconRightPress} style={[styles.iconContainer, styles.iconRight]}>
<CustomIcon name={iconRight} style={{ color: themes[theme].bodyText }} size={20} /> <CustomIcon name={iconRight} style={{ color: themes[theme].bodyText }} size={20} />
</BorderlessButton> </Touchable>
); );
} }
@ -105,14 +105,14 @@ export default class RCTextInput extends React.PureComponent<IRCTextInputProps,
const { showPassword } = this.state; const { showPassword } = this.state;
const { testID, theme } = this.props; const { testID, theme } = this.props;
return ( return (
<BorderlessButton onPress={this.tooglePassword} style={[styles.iconContainer, styles.iconRight]}> <Touchable onPress={this.tooglePassword} style={[styles.iconContainer, styles.iconRight]}>
<CustomIcon <CustomIcon
name={showPassword ? 'unread-on-top' : 'unread-on-top-disabled'} name={showPassword ? 'unread-on-top' : 'unread-on-top-disabled'}
testID={testID ? `${testID}-icon-right` : null} testID={testID ? `${testID}-icon-right` : null}
style={{ color: themes[theme].auxiliaryText }} style={{ color: themes[theme].auxiliaryText }}
size={20} size={20}
/> />
</BorderlessButton> </Touchable>
); );
} }

View File

@ -51,7 +51,9 @@ class QueueListView extends React.Component {
server: PropTypes.string, server: PropTypes.string,
useRealName: PropTypes.bool, useRealName: PropTypes.bool,
navigation: PropTypes.object, navigation: PropTypes.object,
theme: PropTypes.string theme: PropTypes.string,
showAvatar: PropTypes.bool,
displayMode: PropTypes.string
}; };
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps) {
@ -95,7 +97,9 @@ class QueueListView extends React.Component {
useRealName, useRealName,
theme, theme,
isMasterDetail, isMasterDetail,
width width,
showAvatar,
displayMode
} = this.props; } = this.props;
const id = this.getUidDirectMessage(item); const id = this.getUidDirectMessage(item);
@ -117,6 +121,8 @@ class QueueListView extends React.Component {
getRoomAvatar={this.getRoomAvatar} getRoomAvatar={this.getRoomAvatar}
visitor={item.v} visitor={item.v}
swipeEnabled={false} swipeEnabled={false}
showAvatar={showAvatar}
displayMode={displayMode}
/> />
); );
}; };
@ -151,6 +157,8 @@ const mapStateToProps = state => ({
isMasterDetail: state.app.isMasterDetail, isMasterDetail: state.app.isMasterDetail,
server: state.server.server, server: state.server.server,
useRealName: state.settings.UI_Use_Real_Name, useRealName: state.settings.UI_Use_Real_Name,
queued: getInquiryQueueSelector(state) queued: getInquiryQueueSelector(state),
showAvatar: state.sortPreferences.showAvatar,
displayMode: state.sortPreferences.displayMode
}); });
export default connect(mapStateToProps)(withDimensions(withTheme(QueueListView))); export default connect(mapStateToProps)(withDimensions(withTheme(QueueListView)));

View File

@ -79,7 +79,6 @@
"error-user-registration-secret": "التسجيل مسموح به عبر عنوان الويب السري فقط", "error-user-registration-secret": "التسجيل مسموح به عبر عنوان الويب السري فقط",
"error-you-are-last-owner": "أنت المالك الأخير. يرجى تعيين مالك جديد قبل مغادرة الغرفة", "error-you-are-last-owner": "أنت المالك الأخير. يرجى تعيين مالك جديد قبل مغادرة الغرفة",
"Actions": "الإجراءات", "Actions": "الإجراءات",
"activity": "نشاط",
"Activity": "النشاط", "Activity": "النشاط",
"Add_Reaction": "إضافة تفاعل", "Add_Reaction": "إضافة تفاعل",
"Add_Server": "إضافة خادم", "Add_Server": "إضافة خادم",
@ -224,7 +223,6 @@
"Everyone_can_access_this_channel": "يمكن للجميع الوصول إلى هذه القناة", "Everyone_can_access_this_channel": "يمكن للجميع الوصول إلى هذه القناة",
"Error_uploading": "خطأ في الرفع", "Error_uploading": "خطأ في الرفع",
"Expiration_Days": "انتهاء (أيام)", "Expiration_Days": "انتهاء (أيام)",
"Favorite": "مفضل",
"Favorites": "مفضلات", "Favorites": "مفضلات",
"Files": "ملفات", "Files": "ملفات",
"File_description": "وصف الملف", "File_description": "وصف الملف",
@ -241,9 +239,6 @@
"Forward_to_user": "إعادة توجيه لمستخدم", "Forward_to_user": "إعادة توجيه لمستخدم",
"Full_table": "انقر لرؤية الجدول كاملاً", "Full_table": "انقر لرؤية الجدول كاملاً",
"Generate_New_Link": "إنشاء رابط جديد", "Generate_New_Link": "إنشاء رابط جديد",
"Group_by_favorites": "جمع حسب المفضلة",
"Group_by_type": "جمع حسب النوع",
"Hide": "إخفاء",
"Has_joined_the_channel": "انضم إلى القناة", "Has_joined_the_channel": "انضم إلى القناة",
"Has_joined_the_conversation": "انضم إلى المحادثة", "Has_joined_the_conversation": "انضم إلى المحادثة",
"Has_left_the_channel": "غادر القناة", "Has_left_the_channel": "غادر القناة",
@ -321,7 +316,6 @@
"My_servers": "الخوادم", "My_servers": "الخوادم",
"N_people_reacted": "{{n}} تفاعل الناس", "N_people_reacted": "{{n}} تفاعل الناس",
"N_users": "{{n}} مستخدمين", "N_users": "{{n}} مستخدمين",
"name": "اسم",
"Name": "اسم", "Name": "اسم",
"Navigation_history": "تاريخ التصفح", "Navigation_history": "تاريخ التصفح",
"Never": "أبداً", "Never": "أبداً",
@ -398,7 +392,6 @@
"Reactions_are_disabled": "التفاعل معطل", "Reactions_are_disabled": "التفاعل معطل",
"Reactions_are_enabled": "التفاعل مفعل", "Reactions_are_enabled": "التفاعل مفعل",
"Reactions": "التفاعلات", "Reactions": "التفاعلات",
"Read": "قراءة",
"Read_External_Permission_Message": "يحتاج Rocket.chat للوصول إلى الصور والملفات الموجودة على الجهاز", "Read_External_Permission_Message": "يحتاج Rocket.chat للوصول إلى الصور والملفات الموجودة على الجهاز",
"Read_External_Permission": "صلاحية قراءة الوسائط", "Read_External_Permission": "صلاحية قراءة الوسائط",
"Read_Only_Channel": "قناة للقراءة فقط", "Read_Only_Channel": "قناة للقراءة فقط",
@ -490,7 +483,6 @@
"Sign_in_your_server": "تسجيل الدخول إلى الخادم الخاص بك", "Sign_in_your_server": "تسجيل الدخول إلى الخادم الخاص بك",
"Sign_Up": "تسجيل جديد", "Sign_Up": "تسجيل جديد",
"Some_field_is_invalid_or_empty": "بعض الحقول غير صالحة أو فارغة", "Some_field_is_invalid_or_empty": "بعض الحقول غير صالحة أو فارغة",
"Sorting_by": "فرز حسب {{key}}",
"Sound": "الصوت", "Sound": "الصوت",
"Star_room": "تمييز الغرفة", "Star_room": "تمييز الغرفة",
"Star": "تمييز", "Star": "تمييز",
@ -529,7 +521,6 @@
"unarchive": "إلغاء الأرشفة", "unarchive": "إلغاء الأرشفة",
"UNARCHIVE": "إلغاء الأرشفة", "UNARCHIVE": "إلغاء الأرشفة",
"Unblock_user": "إلغاء حظر عن مستخدم", "Unblock_user": "إلغاء حظر عن مستخدم",
"Unfavorite": "إزالة من المفضلة",
"Unfollowed_thread": "موضوع غير متابع", "Unfollowed_thread": "موضوع غير متابع",
"Unmute": "إلغاء كتم", "Unmute": "إلغاء كتم",
"unmuted": "إلغاء كتم", "unmuted": "إلغاء كتم",

View File

@ -81,7 +81,6 @@
"error-you-are-last-owner": "Du bist der letzte Besitzer. Bitte setze einen neuen Besitzer, bevor du den Raum verlässt.", "error-you-are-last-owner": "Du bist der letzte Besitzer. Bitte setze einen neuen Besitzer, bevor du den Raum verlässt.",
"error-status-not-allowed": "Unsichtbar-Status ist deaktiviert", "error-status-not-allowed": "Unsichtbar-Status ist deaktiviert",
"Actions": "Aktionen", "Actions": "Aktionen",
"activity": "Aktivität",
"Activity": "Aktivität", "Activity": "Aktivität",
"Add_Reaction": "Reaktion hinzufügen", "Add_Reaction": "Reaktion hinzufügen",
"Add_Server": "Server hinzufügen", "Add_Server": "Server hinzufügen",
@ -232,7 +231,6 @@
"Everyone_can_access_this_team": "Jeder kann auf dieses Team zugreifen", "Everyone_can_access_this_team": "Jeder kann auf dieses Team zugreifen",
"Error_uploading": "Fehler beim Hochladen", "Error_uploading": "Fehler beim Hochladen",
"Expiration_Days": "läuft ab (Tage)", "Expiration_Days": "läuft ab (Tage)",
"Favorite": "Favorisieren",
"Favorites": "Favoriten", "Favorites": "Favoriten",
"Files": "Dateien", "Files": "Dateien",
"File_description": "Dateibeschreibung", "File_description": "Dateibeschreibung",
@ -249,9 +247,6 @@
"Forward_to_user": "Weiterleiten an Benutzer", "Forward_to_user": "Weiterleiten an Benutzer",
"Full_table": "Klicken um die ganze Tabelle anzuzeigen", "Full_table": "Klicken um die ganze Tabelle anzuzeigen",
"Generate_New_Link": "Neuen Link erstellen", "Generate_New_Link": "Neuen Link erstellen",
"Group_by_favorites": "Nach Favoriten gruppieren",
"Group_by_type": "Gruppieren nach Typ",
"Hide": "Ausblenden",
"Has_joined_the_channel": "Ist dem Kanal beigetreten", "Has_joined_the_channel": "Ist dem Kanal beigetreten",
"Has_joined_the_conversation": "Hat sich dem Gespräch angeschlossen", "Has_joined_the_conversation": "Hat sich dem Gespräch angeschlossen",
"Has_left_the_channel": "Hat den Kanal verlassen", "Has_left_the_channel": "Hat den Kanal verlassen",
@ -334,7 +329,6 @@
"N_people_reacted": "{{n}} Leute haben reagiert", "N_people_reacted": "{{n}} Leute haben reagiert",
"N_users": "{{n}} Benutzer", "N_users": "{{n}} Benutzer",
"N_channels": "{{n}} Kanäle", "N_channels": "{{n}} Kanäle",
"name": "Name",
"Name": "Name", "Name": "Name",
"Navigation_history": "Navigations-Verlauf", "Navigation_history": "Navigations-Verlauf",
"Never": "Niemals", "Never": "Niemals",
@ -412,7 +406,6 @@
"Reactions_are_disabled": "Reaktionen sind deaktiviert", "Reactions_are_disabled": "Reaktionen sind deaktiviert",
"Reactions_are_enabled": "Reaktionen sind aktiviert", "Reactions_are_enabled": "Reaktionen sind aktiviert",
"Reactions": "Reaktionen", "Reactions": "Reaktionen",
"Read": "Gelesen",
"Read_External_Permission_Message": "Rocket.Chat benötigt Zugriff auf deine Fotos, Medien und Dateien auf deinem Gerät", "Read_External_Permission_Message": "Rocket.Chat benötigt Zugriff auf deine Fotos, Medien und Dateien auf deinem Gerät",
"Read_External_Permission": "Lese-Zugriff auf Medien", "Read_External_Permission": "Lese-Zugriff auf Medien",
"Read_Only_Channel": "Nur-Lese-Kanal", "Read_Only_Channel": "Nur-Lese-Kanal",
@ -507,7 +500,6 @@
"Sign_in_your_server": "Melde dich bei deinem Server an", "Sign_in_your_server": "Melde dich bei deinem Server an",
"Sign_Up": "Anmelden", "Sign_Up": "Anmelden",
"Some_field_is_invalid_or_empty": "Ein Feld ist ungültig oder leer", "Some_field_is_invalid_or_empty": "Ein Feld ist ungültig oder leer",
"Sorting_by": "Sortierung nach {{key}}",
"Sound": "Ton", "Sound": "Ton",
"Star_room": "Favorisierter Raum", "Star_room": "Favorisierter Raum",
"Star": "Favoriten", "Star": "Favoriten",
@ -546,7 +538,6 @@
"unarchive": "wiederherstellen", "unarchive": "wiederherstellen",
"UNARCHIVE": "WIEDERHERSTELLEN", "UNARCHIVE": "WIEDERHERSTELLEN",
"Unblock_user": "Benutzer entsperren", "Unblock_user": "Benutzer entsperren",
"Unfavorite": "Nicht mehr favorisieren",
"Unfollowed_thread": "Thread nicht mehr folgen", "Unfollowed_thread": "Thread nicht mehr folgen",
"Unmute": "Stummschaltung aufheben", "Unmute": "Stummschaltung aufheben",
"unmuted": "Stummschaltung aufgehoben", "unmuted": "Stummschaltung aufgehoben",

View File

@ -81,7 +81,6 @@
"error-you-are-last-owner": "You are the last owner. Please set new owner before leaving the room.", "error-you-are-last-owner": "You are the last owner. Please set new owner before leaving the room.",
"error-status-not-allowed": "Invisible status is disabled", "error-status-not-allowed": "Invisible status is disabled",
"Actions": "Actions", "Actions": "Actions",
"activity": "activity",
"Activity": "Activity", "Activity": "Activity",
"Add_Reaction": "Add Reaction", "Add_Reaction": "Add Reaction",
"Add_Server": "Add Server", "Add_Server": "Add Server",
@ -232,7 +231,6 @@
"Everyone_can_access_this_team": "Everyone can access this team", "Everyone_can_access_this_team": "Everyone can access this team",
"Error_uploading": "Error uploading", "Error_uploading": "Error uploading",
"Expiration_Days": "Expiration (Days)", "Expiration_Days": "Expiration (Days)",
"Favorite": "Favorite",
"Favorites": "Favorites", "Favorites": "Favorites",
"Files": "Files", "Files": "Files",
"File_description": "File description", "File_description": "File description",
@ -249,9 +247,6 @@
"Forward_to_user": "Forward to user", "Forward_to_user": "Forward to user",
"Full_table": "Click to see full table", "Full_table": "Click to see full table",
"Generate_New_Link": "Generate New Link", "Generate_New_Link": "Generate New Link",
"Group_by_favorites": "Group favorites",
"Group_by_type": "Group by type",
"Hide": "Hide",
"Has_joined_the_channel": "has joined the channel", "Has_joined_the_channel": "has joined the channel",
"Has_joined_the_conversation": "has joined the conversation", "Has_joined_the_conversation": "has joined the conversation",
"Has_left_the_channel": "has left the channel", "Has_left_the_channel": "has left the channel",
@ -334,7 +329,6 @@
"N_people_reacted": "{{n}} people reacted", "N_people_reacted": "{{n}} people reacted",
"N_users": "{{n}} users", "N_users": "{{n}} users",
"N_channels": "{{n}} channels", "N_channels": "{{n}} channels",
"name": "name",
"Name": "Name", "Name": "Name",
"Navigation_history": "Navigation history", "Navigation_history": "Navigation history",
"Never": "Never", "Never": "Never",
@ -412,7 +406,6 @@
"Reactions_are_disabled": "Reactions are disabled", "Reactions_are_disabled": "Reactions are disabled",
"Reactions_are_enabled": "Reactions are enabled", "Reactions_are_enabled": "Reactions are enabled",
"Reactions": "Reactions", "Reactions": "Reactions",
"Read": "Read",
"Read_External_Permission_Message": "Rocket.Chat needs to access photos, media, and files on your device", "Read_External_Permission_Message": "Rocket.Chat needs to access photos, media, and files on your device",
"Read_External_Permission": "Read Media Permission", "Read_External_Permission": "Read Media Permission",
"Read_Only_Channel": "Read Only Channel", "Read_Only_Channel": "Read Only Channel",
@ -507,7 +500,6 @@
"Sign_in_your_server": "Sign in your server", "Sign_in_your_server": "Sign in your server",
"Sign_Up": "Sign Up", "Sign_Up": "Sign Up",
"Some_field_is_invalid_or_empty": "Some field is invalid or empty", "Some_field_is_invalid_or_empty": "Some field is invalid or empty",
"Sorting_by": "Sorting by {{key}}",
"Sound": "Sound", "Sound": "Sound",
"Star_room": "Star room", "Star_room": "Star room",
"Star": "Star", "Star": "Star",
@ -546,7 +538,6 @@
"unarchive": "unarchive", "unarchive": "unarchive",
"UNARCHIVE": "UNARCHIVE", "UNARCHIVE": "UNARCHIVE",
"Unblock_user": "Unblock user", "Unblock_user": "Unblock user",
"Unfavorite": "Unfavorite",
"Unfollowed_thread": "Unfollowed thread", "Unfollowed_thread": "Unfollowed thread",
"Unmute": "Unmute", "Unmute": "Unmute",
"unmuted": "unmuted", "unmuted": "unmuted",
@ -772,6 +763,13 @@
"Converting_Team_To_Channel": "Converting Team to Channel", "Converting_Team_To_Channel": "Converting Team to Channel",
"Select_Team_Channels_To_Delete": "Select the Teams Channels you would like to delete, the ones you do not select will be moved to the Workspace. \n\nNotice that public Channels will be public and visible to everyone.", "Select_Team_Channels_To_Delete": "Select the Teams Channels you would like to delete, the ones you do not select will be moved to the Workspace. \n\nNotice that public Channels will be public and visible to everyone.",
"You_are_converting_the_team": "You are converting this Team to a Channel", "You_are_converting_the_team": "You are converting this Team to a Channel",
"Display": "Display",
"Avatars": "Avatars",
"Sort_by": "Sort by",
"Group_by": "Group by",
"Types": "Types",
"Expanded": "Expanded",
"Condensed": "Condensed",
"creating_discussion": "creating discussion", "creating_discussion": "creating discussion",
"Canned_Responses": "Canned Responses", "Canned_Responses": "Canned Responses",
"No_match_found": "No match found.", "No_match_found": "No match found.",

View File

@ -76,7 +76,6 @@
"error-user-registration-secret": "El registro de usuarios sólo está permitido por URL secretas", "error-user-registration-secret": "El registro de usuarios sólo está permitido por URL secretas",
"error-you-are-last-owner": "Eres el único propietario existente. Debes establecer un nuevo propietario antes de abandonar la sala.", "error-you-are-last-owner": "Eres el único propietario existente. Debes establecer un nuevo propietario antes de abandonar la sala.",
"Actions": "Acciones", "Actions": "Acciones",
"activity": "actividad",
"Activity": "Actividad", "Activity": "Actividad",
"Add_Reaction": "Añadir reacción", "Add_Reaction": "Añadir reacción",
"Add_Server": "Añadir servidor", "Add_Server": "Añadir servidor",
@ -176,7 +175,6 @@
"Enable_notifications": "Permitir notificaciones", "Enable_notifications": "Permitir notificaciones",
"Everyone_can_access_this_channel": "Todos los usuarios pueden acceder a este canal", "Everyone_can_access_this_channel": "Todos los usuarios pueden acceder a este canal",
"Error_uploading": "Error en la subida", "Error_uploading": "Error en la subida",
"Favorite": "Favorito",
"Favorites": "Favoritos", "Favorites": "Favoritos",
"Files": "Archivos", "Files": "Archivos",
"File_description": "Descripción del archivo", "File_description": "Descripción del archivo",
@ -188,9 +186,6 @@
"Forgot_password": "¿Ha olvidado su contraseña?", "Forgot_password": "¿Ha olvidado su contraseña?",
"Forgot_Password": "Olvidé la contraseña", "Forgot_Password": "Olvidé la contraseña",
"Full_table": "Click para ver la tabla completa", "Full_table": "Click para ver la tabla completa",
"Group_by_favorites": "Agrupar por favoritos",
"Group_by_type": "Agrupar por tipo",
"Hide": "Ocultar",
"Has_joined_the_channel": "se ha unido al canal", "Has_joined_the_channel": "se ha unido al canal",
"Has_joined_the_conversation": "se ha unido a la conversación", "Has_joined_the_conversation": "se ha unido a la conversación",
"Has_left_the_channel": "ha dejado el canal", "Has_left_the_channel": "ha dejado el canal",
@ -237,7 +232,6 @@
"My_servers": "Mis servidores", "My_servers": "Mis servidores",
"N_people_reacted": "Han reaccionado {{n}} personas", "N_people_reacted": "Han reaccionado {{n}} personas",
"N_users": "{{n}} usuarios", "N_users": "{{n}} usuarios",
"name": "nombre",
"Name": "Nombre", "Name": "Nombre",
"New_Message": "Nuevo mensaje", "New_Message": "Nuevo mensaje",
"New_Password": "Nueva contraseña", "New_Password": "Nueva contraseña",
@ -292,7 +286,6 @@
"Reactions_are_disabled": "Las reacciones están desactivadas", "Reactions_are_disabled": "Las reacciones están desactivadas",
"Reactions_are_enabled": "Las reacciones están activadas", "Reactions_are_enabled": "Las reacciones están activadas",
"Reactions": "Reacciones", "Reactions": "Reacciones",
"Read": "Leer",
"Read_Only_Channel": "Canal de sólo lectura", "Read_Only_Channel": "Canal de sólo lectura",
"Read_Only": "Sólo lectura ", "Read_Only": "Sólo lectura ",
"Read_Receipt": "Comprobante de lectura", "Read_Receipt": "Comprobante de lectura",
@ -356,7 +349,6 @@
"Sign_in_your_server": "Accede a tu servidor", "Sign_in_your_server": "Accede a tu servidor",
"Sign_Up": "Registrarse", "Sign_Up": "Registrarse",
"Some_field_is_invalid_or_empty": "Algún campo no es correcto o está vacío", "Some_field_is_invalid_or_empty": "Algún campo no es correcto o está vacío",
"Sorting_by": "Ordenado por {{key}}",
"Sound": "Sonido", "Sound": "Sonido",
"Star_room": "Destacar sala", "Star_room": "Destacar sala",
"Star": "Destacar", "Star": "Destacar",
@ -390,7 +382,6 @@
"unarchive": "desarchivar", "unarchive": "desarchivar",
"UNARCHIVE": "DESARCHIVAR", "UNARCHIVE": "DESARCHIVAR",
"Unblock_user": "Desbloquear usuario", "Unblock_user": "Desbloquear usuario",
"Unfavorite": "Quitar favorito",
"Unfollowed_thread": "Dejar de seguir el hilo", "Unfollowed_thread": "Dejar de seguir el hilo",
"Unmute": "Desmutear", "Unmute": "Desmutear",
"unmuted": "Desmuteado", "unmuted": "Desmuteado",

View File

@ -81,7 +81,6 @@
"error-you-are-last-owner": "Vous êtes le dernier propriétaire. Veuillez définir un nouveau propriétaire avant de quitter le salon.", "error-you-are-last-owner": "Vous êtes le dernier propriétaire. Veuillez définir un nouveau propriétaire avant de quitter le salon.",
"error-status-not-allowed": "Le statut invisible est désactivé", "error-status-not-allowed": "Le statut invisible est désactivé",
"Actions": "Actions", "Actions": "Actions",
"activity": "activité",
"Activity": "Activité", "Activity": "Activité",
"Add_Reaction": "Ajouter une réaction", "Add_Reaction": "Ajouter une réaction",
"Add_Server": "Ajouter un serveur", "Add_Server": "Ajouter un serveur",
@ -232,7 +231,6 @@
"Everyone_can_access_this_team": "Tout le monde peut accéder à cette équipe", "Everyone_can_access_this_team": "Tout le monde peut accéder à cette équipe",
"Error_uploading": "Erreur lors de l'envoi", "Error_uploading": "Erreur lors de l'envoi",
"Expiration_Days": "Expiration (Jours)", "Expiration_Days": "Expiration (Jours)",
"Favorite": "Favori",
"Favorites": "Favoris", "Favorites": "Favoris",
"Files": "Fichiers", "Files": "Fichiers",
"File_description": "Description du fichier", "File_description": "Description du fichier",
@ -249,9 +247,6 @@
"Forward_to_user": "Transmettre à l'utilisateur", "Forward_to_user": "Transmettre à l'utilisateur",
"Full_table": "Cliquez pour voir le tableau complet", "Full_table": "Cliquez pour voir le tableau complet",
"Generate_New_Link": "Générer un nouveau lien", "Generate_New_Link": "Générer un nouveau lien",
"Group_by_favorites": "Grouper par favoris",
"Group_by_type": "Grouper par type",
"Hide": "Cacher",
"Has_joined_the_channel": "a rejoint le canal", "Has_joined_the_channel": "a rejoint le canal",
"Has_joined_the_conversation": "a rejoint la conversation", "Has_joined_the_conversation": "a rejoint la conversation",
"Has_left_the_channel": "a quitté le canal", "Has_left_the_channel": "a quitté le canal",
@ -334,7 +329,6 @@
"N_people_reacted": "{{n}} personnes ont réagi", "N_people_reacted": "{{n}} personnes ont réagi",
"N_users": "{{n}} utilisateurs", "N_users": "{{n}} utilisateurs",
"N_channels": "{{n}} canaux", "N_channels": "{{n}} canaux",
"name": "nom",
"Name": "Nom", "Name": "Nom",
"Navigation_history": "Historique de navigation", "Navigation_history": "Historique de navigation",
"Never": "Jamais", "Never": "Jamais",
@ -412,7 +406,6 @@
"Reactions_are_disabled": "Les réactions sont désactivées", "Reactions_are_disabled": "Les réactions sont désactivées",
"Reactions_are_enabled": "Les réactions sont activées", "Reactions_are_enabled": "Les réactions sont activées",
"Reactions": "Réactions", "Reactions": "Réactions",
"Read": "Lecture",
"Read_External_Permission_Message": "Rocket.Chat doit accéder aux photos, aux médias et aux fichiers sur votre appareil", "Read_External_Permission_Message": "Rocket.Chat doit accéder aux photos, aux médias et aux fichiers sur votre appareil",
"Read_External_Permission": "Permission de lecture des fichiers", "Read_External_Permission": "Permission de lecture des fichiers",
"Read_Only_Channel": "Canal en lecture seule", "Read_Only_Channel": "Canal en lecture seule",
@ -507,7 +500,6 @@
"Sign_in_your_server": "Connectez-vous à votre serveur", "Sign_in_your_server": "Connectez-vous à votre serveur",
"Sign_Up": "S'inscrire", "Sign_Up": "S'inscrire",
"Some_field_is_invalid_or_empty": "Certains champs sont invalides ou vides", "Some_field_is_invalid_or_empty": "Certains champs sont invalides ou vides",
"Sorting_by": "Tri par {{key}}",
"Sound": "Son", "Sound": "Son",
"Star_room": "Canal favoris", "Star_room": "Canal favoris",
"Star": "Mettre en favoris", "Star": "Mettre en favoris",
@ -546,7 +538,6 @@
"unarchive": "désarchiver", "unarchive": "désarchiver",
"UNARCHIVE": "DÉSARCHIVER", "UNARCHIVE": "DÉSARCHIVER",
"Unblock_user": "Débloquer l'utilisateur", "Unblock_user": "Débloquer l'utilisateur",
"Unfavorite": "Supprimer des favoris",
"Unfollowed_thread": "Ne plus suivre ce fil", "Unfollowed_thread": "Ne plus suivre ce fil",
"Unmute": "Rendre la parole", "Unmute": "Rendre la parole",
"unmuted": "rendu la parole", "unmuted": "rendu la parole",

View File

@ -79,7 +79,6 @@
"error-user-registration-secret": "Registrazione utente permessa solo via URL segreto", "error-user-registration-secret": "Registrazione utente permessa solo via URL segreto",
"error-you-are-last-owner": "Sei l'ultimo proprietario rimasto. Imposta un nuovo proprietario prima di lasciare la stanza.", "error-you-are-last-owner": "Sei l'ultimo proprietario rimasto. Imposta un nuovo proprietario prima di lasciare la stanza.",
"Actions": "Azioni", "Actions": "Azioni",
"activity": "attività",
"Activity": "Attività", "Activity": "Attività",
"Add_Reaction": "Aggiungi reazione", "Add_Reaction": "Aggiungi reazione",
"Add_Server": "Aggiungi server", "Add_Server": "Aggiungi server",
@ -227,7 +226,6 @@
"Everyone_can_access_this_channel": "Tutti hanno accesso a questo canale", "Everyone_can_access_this_channel": "Tutti hanno accesso a questo canale",
"Error_uploading": "Errore nel caricamento di", "Error_uploading": "Errore nel caricamento di",
"Expiration_Days": "Scadenza (giorni)", "Expiration_Days": "Scadenza (giorni)",
"Favorite": "Preferito",
"Favorites": "Preferiti", "Favorites": "Preferiti",
"Files": "File", "Files": "File",
"File_description": "Descrizione file", "File_description": "Descrizione file",
@ -244,9 +242,6 @@
"Forward_to_user": "Inoltra ad udente", "Forward_to_user": "Inoltra ad udente",
"Full_table": "Clicca per la tabella completa", "Full_table": "Clicca per la tabella completa",
"Generate_New_Link": "Genera nuovo link", "Generate_New_Link": "Genera nuovo link",
"Group_by_favorites": "Raggruppa per preferiti",
"Group_by_type": "Raggruppa per tipo",
"Hide": "Nascondi",
"Has_joined_the_channel": "si è unito al canale", "Has_joined_the_channel": "si è unito al canale",
"Has_joined_the_conversation": "si è unito alla conversazione", "Has_joined_the_conversation": "si è unito alla conversazione",
"Has_left_the_channel": "ha lasciato il canale", "Has_left_the_channel": "ha lasciato il canale",
@ -326,7 +321,6 @@
"My_servers": "I miei server", "My_servers": "I miei server",
"N_people_reacted": "{{n}} persone hanno reagito", "N_people_reacted": "{{n}} persone hanno reagito",
"N_users": "{{n}} utenti", "N_users": "{{n}} utenti",
"name": "nome",
"Name": "Nome", "Name": "Nome",
"Navigation_history": "Cronologia di navigazione", "Navigation_history": "Cronologia di navigazione",
"Never": "Mai", "Never": "Mai",
@ -404,7 +398,6 @@
"Reactions_are_disabled": "Le reazioni sono disabilitate", "Reactions_are_disabled": "Le reazioni sono disabilitate",
"Reactions_are_enabled": "Le reazioni sono abilitate", "Reactions_are_enabled": "Le reazioni sono abilitate",
"Reactions": "Reazioni", "Reactions": "Reazioni",
"Read": "Letto",
"Read_External_Permission_Message": "Rocket.Chat deve accedere alle foto, media, e documenti sul tuo dispositivo", "Read_External_Permission_Message": "Rocket.Chat deve accedere alle foto, media, e documenti sul tuo dispositivo",
"Read_External_Permission": "Permesso di Lettura della Memoria", "Read_External_Permission": "Permesso di Lettura della Memoria",
"Read_Only_Channel": "Canale in sola lettura", "Read_Only_Channel": "Canale in sola lettura",
@ -498,7 +491,6 @@
"Sign_in_your_server": "Accedi al tuo server", "Sign_in_your_server": "Accedi al tuo server",
"Sign_Up": "Registrati", "Sign_Up": "Registrati",
"Some_field_is_invalid_or_empty": "Un campo non è valido o è vuoto", "Some_field_is_invalid_or_empty": "Un campo non è valido o è vuoto",
"Sorting_by": "Ordina per {{key}}",
"Sound": "Suono", "Sound": "Suono",
"Star_room": "Aggiungi stanza ai preferiti", "Star_room": "Aggiungi stanza ai preferiti",
"Star": "Aggiungi ai preferiti", "Star": "Aggiungi ai preferiti",
@ -537,7 +529,6 @@
"unarchive": "rimuovi dall'archivio", "unarchive": "rimuovi dall'archivio",
"UNARCHIVE": "RIMUOVI DALL'ARCHIVIO", "UNARCHIVE": "RIMUOVI DALL'ARCHIVIO",
"Unblock_user": "Sblocca utente", "Unblock_user": "Sblocca utente",
"Unfavorite": "Rimuovi preferito",
"Unfollowed_thread": "Non segui più il thread", "Unfollowed_thread": "Non segui più il thread",
"Unmute": "Attiva notifiche", "Unmute": "Attiva notifiche",
"unmuted": "notifiche attivate", "unmuted": "notifiche attivate",

View File

@ -77,7 +77,6 @@
"error-user-registration-secret": "ユーザーの登録は登録用URLからのみ許可されています", "error-user-registration-secret": "ユーザーの登録は登録用URLからのみ許可されています",
"error-you-are-last-owner": "あなたは最後のオーナーです。ルームを退出する前に別のオーナーを設定してください。", "error-you-are-last-owner": "あなたは最後のオーナーです。ルームを退出する前に別のオーナーを設定してください。",
"Actions": "アクション", "Actions": "アクション",
"activity": "アクティビティ",
"Activity": "アクティビティ順", "Activity": "アクティビティ順",
"Add_Reaction": "リアクションを追加", "Add_Reaction": "リアクションを追加",
"Add_Server": "サーバーを追加", "Add_Server": "サーバーを追加",
@ -183,7 +182,6 @@
"Everyone_can_access_this_channel": "全員このチャンネルにアクセスできます", "Everyone_can_access_this_channel": "全員このチャンネルにアクセスできます",
"Error_uploading": "アップロードエラー", "Error_uploading": "アップロードエラー",
"Expiration_Days": "期限切れ (日)", "Expiration_Days": "期限切れ (日)",
"Favorite": "お気に入り",
"Favorites": "お気に入り", "Favorites": "お気に入り",
"Files": "ファイル", "Files": "ファイル",
"File_description": "ファイルの説明", "File_description": "ファイルの説明",
@ -196,9 +194,6 @@
"Forgot_Password": "パスワードを忘れた", "Forgot_Password": "パスワードを忘れた",
"Full_table": "クリックしてテーブル全体を見る", "Full_table": "クリックしてテーブル全体を見る",
"Generate_New_Link": "新しいリンクを生成", "Generate_New_Link": "新しいリンクを生成",
"Group_by_favorites": "お気に入りをグループ化",
"Group_by_type": "タイプ別にグループ化",
"Hide": "隠す",
"Has_joined_the_channel": "はチャンネルに参加しました", "Has_joined_the_channel": "はチャンネルに参加しました",
"Has_joined_the_conversation": "は会話に参加しました", "Has_joined_the_conversation": "は会話に参加しました",
"Has_left_the_channel": "はチャンネルを退出しました", "Has_left_the_channel": "はチャンネルを退出しました",
@ -251,7 +246,6 @@
"My_servers": "自分のサーバー", "My_servers": "自分のサーバー",
"N_people_reacted": "{{n}}人がリアクションしました", "N_people_reacted": "{{n}}人がリアクションしました",
"N_users": "{{n}}人", "N_users": "{{n}}人",
"name": "アルファベット",
"Name": "名前", "Name": "名前",
"Never": "ずっと受け取らない", "Never": "ずっと受け取らない",
"New_Message": "メッセージ", "New_Message": "メッセージ",
@ -308,7 +302,6 @@
"Reactions_are_disabled": "リアクションは無効化されています", "Reactions_are_disabled": "リアクションは無効化されています",
"Reactions_are_enabled": "リアクションは有効化されています", "Reactions_are_enabled": "リアクションは有効化されています",
"Reactions": "リアクション", "Reactions": "リアクション",
"Read": "読む",
"Read_Only_Channel": "読み取り専用チャンネル", "Read_Only_Channel": "読み取り専用チャンネル",
"Read_Only": "読み取り専用", "Read_Only": "読み取り専用",
"Read_Receipt": "レシートを見る", "Read_Receipt": "レシートを見る",
@ -382,7 +375,6 @@
"Sign_in_your_server": "サーバーに接続", "Sign_in_your_server": "サーバーに接続",
"Sign_Up": "登録", "Sign_Up": "登録",
"Some_field_is_invalid_or_empty": "不正、または空の入力欄があります。", "Some_field_is_invalid_or_empty": "不正、または空の入力欄があります。",
"Sorting_by": "{{key}}順",
"Sound": "音", "Sound": "音",
"Star_room": "お気に入りルーム", "Star_room": "お気に入りルーム",
"Star": "お気に入り", "Star": "お気に入り",
@ -416,7 +408,6 @@
"unarchive": "アーカイブ解除", "unarchive": "アーカイブ解除",
"UNARCHIVE": "アーカイブ解除", "UNARCHIVE": "アーカイブ解除",
"Unblock_user": "ブロックを解除", "Unblock_user": "ブロックを解除",
"Unfavorite": "お気に入り解除",
"Unfollowed_thread": "スレッド更新時に通知しない", "Unfollowed_thread": "スレッド更新時に通知しない",
"Unmute": "ミュート解除", "Unmute": "ミュート解除",
"unmuted": "ミュート解除しました", "unmuted": "ミュート解除しました",

View File

@ -81,7 +81,6 @@
"error-you-are-last-owner": "Je bent de laatste eigenaar. Stel een nieuwe eigenaar in voordat je de kamer verlaat.", "error-you-are-last-owner": "Je bent de laatste eigenaar. Stel een nieuwe eigenaar in voordat je de kamer verlaat.",
"error-status-not-allowed": "Onzichtbare status is uitgeschakeld", "error-status-not-allowed": "Onzichtbare status is uitgeschakeld",
"Actions": "Acties", "Actions": "Acties",
"activity": "activiteit",
"Activity": "Activiteit", "Activity": "Activiteit",
"Add_Reaction": "Reactie toevoegen", "Add_Reaction": "Reactie toevoegen",
"Add_Server": "Server toevoegen", "Add_Server": "Server toevoegen",
@ -232,7 +231,6 @@
"Everyone_can_access_this_team": "Iedereen heeft toegang tot dit team", "Everyone_can_access_this_team": "Iedereen heeft toegang tot dit team",
"Error_uploading": "Fout bij uploaden", "Error_uploading": "Fout bij uploaden",
"Expiration_Days": "Vervaldatum (Dagen)", "Expiration_Days": "Vervaldatum (Dagen)",
"Favorite": "Favoriet",
"Favorites": "Favorieten", "Favorites": "Favorieten",
"Files": "Bestanden", "Files": "Bestanden",
"File_description": "Bestandsbeschrijving", "File_description": "Bestandsbeschrijving",
@ -249,9 +247,6 @@
"Forward_to_user": "Doorsturen naar gebruiker", "Forward_to_user": "Doorsturen naar gebruiker",
"Full_table": "Klik om de volledige tabel te zien", "Full_table": "Klik om de volledige tabel te zien",
"Generate_New_Link": "Nieuwe link genereren", "Generate_New_Link": "Nieuwe link genereren",
"Group_by_favorites": "Groepeer favorieten",
"Group_by_type": "Groeperen op type",
"Hide": "Verberg",
"Has_joined_the_channel": "is bij het kanaal gekomen", "Has_joined_the_channel": "is bij het kanaal gekomen",
"Has_joined_the_conversation": "heeft zich bij het gesprek aangesloten", "Has_joined_the_conversation": "heeft zich bij het gesprek aangesloten",
"Has_left_the_channel": "heeft het kanaal verlaten", "Has_left_the_channel": "heeft het kanaal verlaten",
@ -334,7 +329,6 @@
"N_people_reacted": "{{n}} mensen hebben gereageerd", "N_people_reacted": "{{n}} mensen hebben gereageerd",
"N_users": "{{n}} gebruikers", "N_users": "{{n}} gebruikers",
"N_channels": "{{n}} kanalen", "N_channels": "{{n}} kanalen",
"name": "naam",
"Name": "Naam", "Name": "Naam",
"Navigation_history": "Navigatie geschiedenis", "Navigation_history": "Navigatie geschiedenis",
"Never": "Nooit", "Never": "Nooit",
@ -412,7 +406,6 @@
"Reactions_are_disabled": "Reacties zijn uitgeschakeld", "Reactions_are_disabled": "Reacties zijn uitgeschakeld",
"Reactions_are_enabled": "Reacties zijn ingeschakeld", "Reactions_are_enabled": "Reacties zijn ingeschakeld",
"Reactions": "Reacties", "Reactions": "Reacties",
"Read": "Lezen",
"Read_External_Permission_Message": "Rocket.Chat heeft toegang nodig tot foto's, media en bestanden op je apparaat", "Read_External_Permission_Message": "Rocket.Chat heeft toegang nodig tot foto's, media en bestanden op je apparaat",
"Read_External_Permission": "Lees toestemming voor media", "Read_External_Permission": "Lees toestemming voor media",
"Read_Only_Channel": "Alleen-lezen kanaal", "Read_Only_Channel": "Alleen-lezen kanaal",
@ -507,7 +500,6 @@
"Sign_in_your_server": "Log in op je server", "Sign_in_your_server": "Log in op je server",
"Sign_Up": "Registreren", "Sign_Up": "Registreren",
"Some_field_is_invalid_or_empty": "Sommige velden zijn ongeldig of leeg", "Some_field_is_invalid_or_empty": "Sommige velden zijn ongeldig of leeg",
"Sorting_by": "Sorteren op {{key}}",
"Sound": "Geluid", "Sound": "Geluid",
"Star_room": "Favoriete kanalen", "Star_room": "Favoriete kanalen",
"Star": "Ster", "Star": "Ster",
@ -546,7 +538,6 @@
"unarchive": "dearchiveren", "unarchive": "dearchiveren",
"UNARCHIVE": "DEARCHIVEREN", "UNARCHIVE": "DEARCHIVEREN",
"Unblock_user": "Deblokkeer gebruiker", "Unblock_user": "Deblokkeer gebruiker",
"Unfavorite": "Uit favorieten halen",
"Unfollowed_thread": "Draad ontvolgd", "Unfollowed_thread": "Draad ontvolgd",
"Unmute": "Dempen opheffen", "Unmute": "Dempen opheffen",
"unmuted": "ongedempt", "unmuted": "ongedempt",

View File

@ -77,7 +77,6 @@
"error-you-are-last-owner": "Você é o último proprietário da sala. Por favor defina um novo proprietário antes de sair.", "error-you-are-last-owner": "Você é o último proprietário da sala. Por favor defina um novo proprietário antes de sair.",
"error-status-not-allowed": "O status invisível está desativado", "error-status-not-allowed": "O status invisível está desativado",
"Actions": "Ações", "Actions": "Ações",
"activity": "atividade",
"Activity": "Atividade", "Activity": "Atividade",
"Add_Reaction": "Reagir", "Add_Reaction": "Reagir",
"Add_Server": "Adicionar servidor", "Add_Server": "Adicionar servidor",
@ -219,7 +218,6 @@
"Everyone_can_access_this_channel": "Todos podem acessar este canal", "Everyone_can_access_this_channel": "Todos podem acessar este canal",
"Error_uploading": "Erro subindo", "Error_uploading": "Erro subindo",
"Expiration_Days": "Expira em (dias)", "Expiration_Days": "Expira em (dias)",
"Favorite": "Adicionar aos Favoritos",
"Favorites": "Favoritos", "Favorites": "Favoritos",
"Files": "Arquivos", "Files": "Arquivos",
"File_description": "Descrição do arquivo", "File_description": "Descrição do arquivo",
@ -236,9 +234,6 @@
"Forward_to_user": "Encaminhar para usuário", "Forward_to_user": "Encaminhar para usuário",
"Full_table": "Clique para ver a tabela completa", "Full_table": "Clique para ver a tabela completa",
"Generate_New_Link": "Gerar novo convite", "Generate_New_Link": "Gerar novo convite",
"Group_by_favorites": "Agrupar favoritos",
"Group_by_type": "Agrupar por tipo",
"Hide": "Ocultar",
"Has_joined_the_channel": "entrou no canal", "Has_joined_the_channel": "entrou no canal",
"Has_joined_the_conversation": "entrou na conversa", "Has_joined_the_conversation": "entrou na conversa",
"Has_left_the_channel": "saiu da conversa", "Has_left_the_channel": "saiu da conversa",
@ -307,7 +302,6 @@
"muted": "mudo", "muted": "mudo",
"N_people_reacted": "{{n}} pessoas reagiram", "N_people_reacted": "{{n}} pessoas reagiram",
"N_users": "{{n}} usuários", "N_users": "{{n}} usuários",
"name": "nome",
"Name": "Nome", "Name": "Nome",
"Navigation_history": "Histórico de navegação", "Navigation_history": "Histórico de navegação",
"Never": "Nunca", "Never": "Nunca",
@ -466,7 +460,6 @@
"Sign_in_your_server": "Entrar no seu servidor", "Sign_in_your_server": "Entrar no seu servidor",
"Sign_Up": "Registrar", "Sign_Up": "Registrar",
"Some_field_is_invalid_or_empty": "Algum campo está inválido ou vazio", "Some_field_is_invalid_or_empty": "Algum campo está inválido ou vazio",
"Sorting_by": "Ordenando por {{key}}",
"Sound": "Som da notificação", "Sound": "Som da notificação",
"Star_room": "Favoritar sala", "Star_room": "Favoritar sala",
"Star": "Favorito", "Star": "Favorito",
@ -502,7 +495,6 @@
"unarchive": "desarquivar", "unarchive": "desarquivar",
"UNARCHIVE": "DESARQUIVAR", "UNARCHIVE": "DESARQUIVAR",
"Unblock_user": "Desbloquear usuário", "Unblock_user": "Desbloquear usuário",
"Unfavorite": "Remover dos Favoritos",
"Unfollowed_thread": "Parou de seguir tópico", "Unfollowed_thread": "Parou de seguir tópico",
"Unmute": "Permitir que o usuário fale", "Unmute": "Permitir que o usuário fale",
"unmuted": "permitiu que o usuário fale", "unmuted": "permitiu que o usuário fale",
@ -673,6 +665,13 @@
"Deleted_The_Team_Successfully": "Time deletado com sucesso", "Deleted_The_Team_Successfully": "Time deletado com sucesso",
"Deleted_The_Room_Successfully": "Sala deletada com sucesso", "Deleted_The_Room_Successfully": "Sala deletada com sucesso",
"Convert_to_Channel": "Converter para um Canal", "Convert_to_Channel": "Converter para um Canal",
"Display": "Display",
"Avatars": "Avatars",
"Sort_by": "Ordenar por",
"Group_by": "Agrupar por",
"Types": "Tipos",
"Expanded": "Estendido",
"Condensed": "Condensado",
"Canned_Responses": "Respostas Predefinidas", "Canned_Responses": "Respostas Predefinidas",
"No_match_found": "Nenhum resultado encontrado", "No_match_found": "Nenhum resultado encontrado",
"Check_canned_responses": "Verifique nas respostas predefinidas", "Check_canned_responses": "Verifique nas respostas predefinidas",

View File

@ -81,7 +81,6 @@
"error-you-are-last-owner": "Você é o último proprietário. Por favor, defina novo proprietário antes de sair da sala.", "error-you-are-last-owner": "Você é o último proprietário. Por favor, defina novo proprietário antes de sair da sala.",
"error-status-not-allowed": "O estado invisível está desactivado", "error-status-not-allowed": "O estado invisível está desactivado",
"Actions": "Acções", "Actions": "Acções",
"activity": "actividade",
"Activity": "Actividade", "Activity": "Actividade",
"Add_Reaction": "Adicionar Reacção", "Add_Reaction": "Adicionar Reacção",
"Add_Server": "Adicionar Servidor", "Add_Server": "Adicionar Servidor",
@ -232,7 +231,6 @@
"Everyone_can_access_this_team": "Todos podem aceder a esta equipa", "Everyone_can_access_this_team": "Todos podem aceder a esta equipa",
"Error_uploading": "Erro ao fazer o envio", "Error_uploading": "Erro ao fazer o envio",
"Expiration_Days": "Validade (Dias)", "Expiration_Days": "Validade (Dias)",
"Favorite": "Favorito",
"Favorites": "Favoritos", "Favorites": "Favoritos",
"Files": "Ficheiros", "Files": "Ficheiros",
"File_description": "Descrição do ficheiro", "File_description": "Descrição do ficheiro",
@ -249,9 +247,6 @@
"Forward_to_user": "Reencaminhar para o utilizador", "Forward_to_user": "Reencaminhar para o utilizador",
"Full_table": "Clique para ver a tabela completa", "Full_table": "Clique para ver a tabela completa",
"Generate_New_Link": "Gerar Novo Link", "Generate_New_Link": "Gerar Novo Link",
"Group_by_favorites": "Agrupar por favoritos",
"Group_by_type": "Agrupar por tipo",
"Hide": "Esconder",
"Has_joined_the_channel": "entrou no canal", "Has_joined_the_channel": "entrou no canal",
"Has_joined_the_conversation": "entrou na conversa", "Has_joined_the_conversation": "entrou na conversa",
"Has_left_the_channel": "saiu do canal", "Has_left_the_channel": "saiu do canal",
@ -333,7 +328,6 @@
"N_people_reacted": "{{n}} pessoas reagiram", "N_people_reacted": "{{n}} pessoas reagiram",
"N_users": "{{n}} utilizadores", "N_users": "{{n}} utilizadores",
"N_channels": "{{n}} canais", "N_channels": "{{n}} canais",
"name": "nome",
"Name": "Nome", "Name": "Nome",
"Navigation_history": "Histórico de navegação", "Navigation_history": "Histórico de navegação",
"Never": "Nunca", "Never": "Nunca",
@ -411,7 +405,6 @@
"Reactions_are_disabled": "Reacções desactivadas", "Reactions_are_disabled": "Reacções desactivadas",
"Reactions_are_enabled": "Reacções activadas", "Reactions_are_enabled": "Reacções activadas",
"Reactions": "Reacções", "Reactions": "Reacções",
"Read": "Ler",
"Read_External_Permission_Message": "Rocket.Chat precisa acessar fotos, média e arquivos em seu dispositivo", "Read_External_Permission_Message": "Rocket.Chat precisa acessar fotos, média e arquivos em seu dispositivo",
"Read_External_Permission": "Permissão de leitura da média", "Read_External_Permission": "Permissão de leitura da média",
"Read_Only_Channel": "Canal só de leitura", "Read_Only_Channel": "Canal só de leitura",
@ -458,7 +451,6 @@
"Sign_in_your_server": "Entre no seu servidor", "Sign_in_your_server": "Entre no seu servidor",
"Sign_Up": "Inscreva-se", "Sign_Up": "Inscreva-se",
"Some_field_is_invalid_or_empty": "Algum campo é inválido ou está vazio", "Some_field_is_invalid_or_empty": "Algum campo é inválido ou está vazio",
"Sorting_by": "Ordenar por {{key}}",
"Star_room": "Marcar como favorito", "Star_room": "Marcar como favorito",
"Star": "Dar estrela", "Star": "Dar estrela",
"Starred_Messages": "Mensagens com estrela", "Starred_Messages": "Mensagens com estrela",

View File

@ -81,7 +81,6 @@
"error-you-are-last-owner": "Вы последний владелец. Пожалуйста, назначьте нового владельца, прежде чем покинуть чат.", "error-you-are-last-owner": "Вы последний владелец. Пожалуйста, назначьте нового владельца, прежде чем покинуть чат.",
"error-status-not-allowed": "Статус Невидимый отключён", "error-status-not-allowed": "Статус Невидимый отключён",
"Actions": "Действия", "Actions": "Действия",
"activity": "активности",
"Activity": "По активности", "Activity": "По активности",
"Add_Reaction": "Добавить реакцию", "Add_Reaction": "Добавить реакцию",
"Add_Server": "Добавить сервер", "Add_Server": "Добавить сервер",
@ -232,7 +231,6 @@
"Everyone_can_access_this_team": "Каждый может получить доступ к этой Команде", "Everyone_can_access_this_team": "Каждый может получить доступ к этой Команде",
"Error_uploading": "Ошибка загрузки", "Error_uploading": "Ошибка загрузки",
"Expiration_Days": "Срок действия (Дни)", "Expiration_Days": "Срок действия (Дни)",
"Favorite": "Избранное",
"Favorites": "Избранные", "Favorites": "Избранные",
"Files": "Файлы", "Files": "Файлы",
"File_description": "Описание файла", "File_description": "Описание файла",
@ -249,9 +247,6 @@
"Forward_to_user": "Перенаправить пользователю", "Forward_to_user": "Перенаправить пользователю",
"Full_table": "Нажмите, чтобы увидеть полную таблицу", "Full_table": "Нажмите, чтобы увидеть полную таблицу",
"Generate_New_Link": "Сгенерировать Новую Ссылку", "Generate_New_Link": "Сгенерировать Новую Ссылку",
"Group_by_favorites": "По избранным",
"Group_by_type": "По типу",
"Hide": "Скрыть",
"Has_joined_the_channel": "присоединился к каналу", "Has_joined_the_channel": "присоединился к каналу",
"Has_joined_the_conversation": "присоединился к беседе", "Has_joined_the_conversation": "присоединился к беседе",
"Has_left_the_channel": "покинул канал", "Has_left_the_channel": "покинул канал",
@ -334,7 +329,6 @@
"N_people_reacted": "отреагировало {{n}} человек", "N_people_reacted": "отреагировало {{n}} человек",
"N_users": "{{n}} пользователи", "N_users": "{{n}} пользователи",
"N_channels": "{{n}} каналов", "N_channels": "{{n}} каналов",
"name": "имя",
"Name": "Имя", "Name": "Имя",
"Navigation_history": "История навигации", "Navigation_history": "История навигации",
"Never": "Никогда", "Never": "Никогда",
@ -412,7 +406,6 @@
"Reactions_are_disabled": "Реакции отключены", "Reactions_are_disabled": "Реакции отключены",
"Reactions_are_enabled": "Реакции активированы", "Reactions_are_enabled": "Реакции активированы",
"Reactions": "Реакции", "Reactions": "Реакции",
"Read": "Читать",
"Read_External_Permission_Message": "Rocket.Chat необходим доступ к фотографиям, медиа и другим файлам на вашем устройстве", "Read_External_Permission_Message": "Rocket.Chat необходим доступ к фотографиям, медиа и другим файлам на вашем устройстве",
"Read_External_Permission": "Разрешение на Чтение Медиа", "Read_External_Permission": "Разрешение на Чтение Медиа",
"Read_Only_Channel": "Канал только для чтения", "Read_Only_Channel": "Канал только для чтения",
@ -507,7 +500,6 @@
"Sign_in_your_server": "Войдите на ваш сервер", "Sign_in_your_server": "Войдите на ваш сервер",
"Sign_Up": "Регистрация", "Sign_Up": "Регистрация",
"Some_field_is_invalid_or_empty": "Некоторые поля недопустимы или пусты", "Some_field_is_invalid_or_empty": "Некоторые поля недопустимы или пусты",
"Sorting_by": "Сортировка по {{key}}",
"Sound": "Звук", "Sound": "Звук",
"Star_room": "В избранное", "Star_room": "В избранное",
"Star": "Отметить", "Star": "Отметить",
@ -546,7 +538,6 @@
"unarchive": "разархивировать", "unarchive": "разархивировать",
"UNARCHIVE": "РАЗАРХИВИРОВАТЬ", "UNARCHIVE": "РАЗАРХИВИРОВАТЬ",
"Unblock_user": "Разблокировать пользователя", "Unblock_user": "Разблокировать пользователя",
"Unfavorite": "Удалить из избранного",
"Unfollowed_thread": "Не следить", "Unfollowed_thread": "Не следить",
"Unmute": "Отменить заглушивание", "Unmute": "Отменить заглушивание",
"unmuted": "Заглушивание отменено", "unmuted": "Заглушивание отменено",

View File

@ -79,7 +79,6 @@
"error-user-registration-secret": "Kullanıcı kaydına yalnızca Gizli URL aracılığıyla izin verilir!", "error-user-registration-secret": "Kullanıcı kaydına yalnızca Gizli URL aracılığıyla izin verilir!",
"error-you-are-last-owner": "Son sahibi sizsiniz. Lütfen odadan ayrılmadan önce yeni bir sahip belirleyin.", "error-you-are-last-owner": "Son sahibi sizsiniz. Lütfen odadan ayrılmadan önce yeni bir sahip belirleyin.",
"Actions": "İşlemler", "Actions": "İşlemler",
"activity": "etkinlik",
"Activity": "Etkinlik", "Activity": "Etkinlik",
"Add_Reaction": "Tepki ekle", "Add_Reaction": "Tepki ekle",
"Add_Server": "Sunucu ekle", "Add_Server": "Sunucu ekle",
@ -227,7 +226,6 @@
"Everyone_can_access_this_channel": "Bu kanala herkes erişebilir", "Everyone_can_access_this_channel": "Bu kanala herkes erişebilir",
"Error_uploading": "Yükleme hatası", "Error_uploading": "Yükleme hatası",
"Expiration_Days": "Geçerlilik Süresi (Gün)", "Expiration_Days": "Geçerlilik Süresi (Gün)",
"Favorite": "Favori",
"Favorites": "Favoriler", "Favorites": "Favoriler",
"Files": "Dosyalar", "Files": "Dosyalar",
"File_description": "Dosya açıklaması", "File_description": "Dosya açıklaması",
@ -244,9 +242,6 @@
"Forward_to_user": "Kullanıcıya İlet", "Forward_to_user": "Kullanıcıya İlet",
"Full_table": "Tam tabloyu görmek için tıklayın", "Full_table": "Tam tabloyu görmek için tıklayın",
"Generate_New_Link": "Yeni Bağlantı Oluştur", "Generate_New_Link": "Yeni Bağlantı Oluştur",
"Group_by_favorites": "Favorilere göre grupla",
"Group_by_type": "Türe göre grupla",
"Hide": "Gizle",
"Has_joined_the_channel": "kanala katıldı", "Has_joined_the_channel": "kanala katıldı",
"Has_joined_the_conversation": "sohbete katıldı", "Has_joined_the_conversation": "sohbete katıldı",
"Has_left_the_channel": "kanaldan ayrıldı", "Has_left_the_channel": "kanaldan ayrıldı",
@ -327,7 +322,6 @@
"My_servers": "Sunucularım", "My_servers": "Sunucularım",
"N_people_reacted": "{{n}} kişi tepki verdi", "N_people_reacted": "{{n}} kişi tepki verdi",
"N_users": "{{n}} kullanıcı", "N_users": "{{n}} kullanıcı",
"name": "isim",
"Name": "İsim", "Name": "İsim",
"Navigation_history": "Gezinti geçmişi", "Navigation_history": "Gezinti geçmişi",
"Never": "Asla", "Never": "Asla",
@ -405,7 +399,6 @@
"Reactions_are_disabled": "Tepkiler devre dışı bırakıldı", "Reactions_are_disabled": "Tepkiler devre dışı bırakıldı",
"Reactions_are_enabled": "Tepkiler etkinleştirildi", "Reactions_are_enabled": "Tepkiler etkinleştirildi",
"Reactions": "Tepkiler", "Reactions": "Tepkiler",
"Read": "Oku",
"Read_External_Permission_Message": "Rocket.Chat'in cihazınızdaki fotoğraflara, medyaya ve dosyalara erişmesi gerekiyor", "Read_External_Permission_Message": "Rocket.Chat'in cihazınızdaki fotoğraflara, medyaya ve dosyalara erişmesi gerekiyor",
"Read_External_Permission": "Medya Okuma İzni ", "Read_External_Permission": "Medya Okuma İzni ",
"Read_Only_Channel": "Yazma Kısıtlı Kanal", "Read_Only_Channel": "Yazma Kısıtlı Kanal",
@ -498,7 +491,6 @@
"Sign_in_your_server": "Sunucunuzda oturum açın", "Sign_in_your_server": "Sunucunuzda oturum açın",
"Sign_Up": "Kaydol", "Sign_Up": "Kaydol",
"Some_field_is_invalid_or_empty": "Bazı alanlar geçersiz veya boş", "Some_field_is_invalid_or_empty": "Bazı alanlar geçersiz veya boş",
"Sorting_by": "{{key}} göre sıralanıyor",
"Sound": "Ses", "Sound": "Ses",
"Star_room": "Odayı Yıldızla", "Star_room": "Odayı Yıldızla",
"Star": "Yıldızla", "Star": "Yıldızla",
@ -537,7 +529,6 @@
"unarchive": "arşivden çıkar", "unarchive": "arşivden çıkar",
"UNARCHIVE": "ARŞİVDEN ÇIKAR", "UNARCHIVE": "ARŞİVDEN ÇIKAR",
"Unblock_user": "Kullanıcının engelini kaldır", "Unblock_user": "Kullanıcının engelini kaldır",
"Unfavorite": "Favorilerden Çıkar",
"Unfollowed_thread": "Takip edilmeyen başlık", "Unfollowed_thread": "Takip edilmeyen başlık",
"Unmute": "Sesi Aç", "Unmute": "Sesi Aç",
"unmuted": "Sesi Açıldı", "unmuted": "Sesi Açıldı",

View File

@ -79,7 +79,6 @@
"error-user-registration-secret": "只能透过加密网址进行用戶注册", "error-user-registration-secret": "只能透过加密网址进行用戶注册",
"error-you-are-last-owner": "您是最后的拥有者。请删除此人之前设置一个新的拥有者。", "error-you-are-last-owner": "您是最后的拥有者。请删除此人之前设置一个新的拥有者。",
"Actions": "操作", "Actions": "操作",
"activity": "活动时间",
"Activity": "按活动时间排列", "Activity": "按活动时间排列",
"Add_Reaction": "增加表情貼", "Add_Reaction": "增加表情貼",
"Add_Server": "創建服务器", "Add_Server": "創建服务器",
@ -227,7 +226,6 @@
"Everyone_can_access_this_channel": "每个人都可以访问此频道", "Everyone_can_access_this_channel": "每个人都可以访问此频道",
"Error_uploading": "错误上传", "Error_uploading": "错误上传",
"Expiration_Days": "到期 (日)", "Expiration_Days": "到期 (日)",
"Favorite": "收藏",
"Favorites": "收藏", "Favorites": "收藏",
"Files": "文件", "Files": "文件",
"File_description": "文件描述", "File_description": "文件描述",
@ -244,9 +242,6 @@
"Forward_to_user": "转发给用戶", "Forward_to_user": "转发给用戶",
"Full_table": "点击以查看完整表格", "Full_table": "点击以查看完整表格",
"Generate_New_Link": "产生新的链接", "Generate_New_Link": "产生新的链接",
"Group_by_favorites": "收藏优先",
"Group_by_type": "以类型分组",
"Hide": "隐藏",
"Has_joined_the_channel": "已加入频道", "Has_joined_the_channel": "已加入频道",
"Has_joined_the_conversation": "已经加入此对话", "Has_joined_the_conversation": "已经加入此对话",
"Has_left_the_channel": "已离开频道", "Has_left_the_channel": "已离开频道",
@ -324,7 +319,6 @@
"My_servers": "我的服务器", "My_servers": "我的服务器",
"N_people_reacted": "{{n}} 人回复", "N_people_reacted": "{{n}} 人回复",
"N_users": "{{n}} 位用户", "N_users": "{{n}} 位用户",
"name": "名称",
"Name": "名称", "Name": "名称",
"Navigation_history": "浏览历史记录", "Navigation_history": "浏览历史记录",
"Never": "从不", "Never": "从不",
@ -402,7 +396,6 @@
"Reactions_are_disabled": "表情貼被禁用", "Reactions_are_disabled": "表情貼被禁用",
"Reactions_are_enabled": "表情貼被启用", "Reactions_are_enabled": "表情貼被启用",
"Reactions": "表情貼", "Reactions": "表情貼",
"Read": "读取",
"Read_External_Permission_Message": "Rocket.Chat 需要存取您装置上的相片、多媒体及文件", "Read_External_Permission_Message": "Rocket.Chat 需要存取您装置上的相片、多媒体及文件",
"Read_External_Permission": "读取媒体权限", "Read_External_Permission": "读取媒体权限",
"Read_Only_Channel": "只读频道", "Read_Only_Channel": "只读频道",
@ -496,7 +489,6 @@
"Sign_in_your_server": "登录你的服务器", "Sign_in_your_server": "登录你的服务器",
"Sign_Up": "注册", "Sign_Up": "注册",
"Some_field_is_invalid_or_empty": "某些字段无效或为空", "Some_field_is_invalid_or_empty": "某些字段无效或为空",
"Sorting_by": "按{{key}}排序",
"Sound": "声音", "Sound": "声音",
"Star_room": "将聊天室标记", "Star_room": "将聊天室标记",
"Star": "标记", "Star": "标记",
@ -535,7 +527,6 @@
"unarchive": "取消封存", "unarchive": "取消封存",
"UNARCHIVE": "取消封存", "UNARCHIVE": "取消封存",
"Unblock_user": "解除屏蔽", "Unblock_user": "解除屏蔽",
"Unfavorite": "取消收藏",
"Unfollowed_thread": "取消追踪讨论", "Unfollowed_thread": "取消追踪讨论",
"Unmute": "取消静音", "Unmute": "取消静音",
"unmuted": "静音状态", "unmuted": "静音状态",

View File

@ -79,7 +79,6 @@
"error-user-registration-secret": "只能透過加密網址進行使用者註冊", "error-user-registration-secret": "只能透過加密網址進行使用者註冊",
"error-you-are-last-owner": "您是最後的擁有者。請刪除此人之前設置一個新的擁有者。", "error-you-are-last-owner": "您是最後的擁有者。請刪除此人之前設置一個新的擁有者。",
"Actions": "操作", "Actions": "操作",
"activity": "活動時間",
"Activity": "以活動時間排序", "Activity": "以活動時間排序",
"Add_Reaction": "增加表情貼", "Add_Reaction": "增加表情貼",
"Add_Server": "新增伺服器", "Add_Server": "新增伺服器",
@ -227,7 +226,6 @@
"Everyone_can_access_this_channel": "所有人皆可存取此頻道", "Everyone_can_access_this_channel": "所有人皆可存取此頻道",
"Error_uploading": "錯誤上傳", "Error_uploading": "錯誤上傳",
"Expiration_Days": "到期 (日)", "Expiration_Days": "到期 (日)",
"Favorite": "我的最愛",
"Favorites": "我的最愛", "Favorites": "我的最愛",
"Files": "檔案", "Files": "檔案",
"File_description": "檔案描述", "File_description": "檔案描述",
@ -244,9 +242,6 @@
"Forward_to_user": "轉發給使用者", "Forward_to_user": "轉發給使用者",
"Full_table": "點擊以查看完整表格", "Full_table": "點擊以查看完整表格",
"Generate_New_Link": "產生新的連結", "Generate_New_Link": "產生新的連結",
"Group_by_favorites": "我的最愛優先",
"Group_by_type": "以類型分組",
"Hide": "隱藏",
"Has_joined_the_channel": "已加入頻道", "Has_joined_the_channel": "已加入頻道",
"Has_joined_the_conversation": "已經加入此對話", "Has_joined_the_conversation": "已經加入此對話",
"Has_left_the_channel": "已離開頻道", "Has_left_the_channel": "已離開頻道",
@ -325,7 +320,6 @@
"My_servers": "我的伺服器", "My_servers": "我的伺服器",
"N_people_reacted": "{{n}} 人回复", "N_people_reacted": "{{n}} 人回复",
"N_users": "{{n}} 位使用者", "N_users": "{{n}} 位使用者",
"name": "名稱",
"Name": "名稱", "Name": "名稱",
"Navigation_history": "瀏覽歷史記錄", "Navigation_history": "瀏覽歷史記錄",
"Never": "從不", "Never": "從不",
@ -403,7 +397,6 @@
"Reactions_are_disabled": "表情貼被禁用", "Reactions_are_disabled": "表情貼被禁用",
"Reactions_are_enabled": "表情貼被啟用", "Reactions_are_enabled": "表情貼被啟用",
"Reactions": "表情貼", "Reactions": "表情貼",
"Read": "讀取",
"Read_External_Permission_Message": "Rocket.Chat 需要存取您裝置上的相片、多媒體及檔案", "Read_External_Permission_Message": "Rocket.Chat 需要存取您裝置上的相片、多媒體及檔案",
"Read_External_Permission": "讀取媒體權限", "Read_External_Permission": "讀取媒體權限",
"Read_Only_Channel": "唯讀頻道", "Read_Only_Channel": "唯讀頻道",
@ -497,7 +490,6 @@
"Sign_in_your_server": "登錄你的伺服器", "Sign_in_your_server": "登錄你的伺服器",
"Sign_Up": "註冊", "Sign_Up": "註冊",
"Some_field_is_invalid_or_empty": "某些字段無效或為空", "Some_field_is_invalid_or_empty": "某些字段無效或為空",
"Sorting_by": "以{{key}}排序",
"Sound": "聲音", "Sound": "聲音",
"Star_room": "標記聊天室", "Star_room": "標記聊天室",
"Star": "標記", "Star": "標記",
@ -536,7 +528,6 @@
"unarchive": "取消封存", "unarchive": "取消封存",
"UNARCHIVE": "取消封存", "UNARCHIVE": "取消封存",
"Unblock_user": "解除封鎖", "Unblock_user": "解除封鎖",
"Unfavorite": "取消最愛",
"Unfollowed_thread": "取消追蹤討論", "Unfollowed_thread": "取消追蹤討論",
"Unmute": "取消靜音", "Unmute": "取消靜音",
"unmuted": "靜音狀態", "unmuted": "靜音狀態",

View File

@ -60,8 +60,7 @@ export const getDatabase = (database = '') => {
Permission, Permission,
SlashCommand, SlashCommand,
User User
], ]
actionsEnabled: true
}); });
}; };
@ -73,8 +72,7 @@ class DB {
schema: serversSchema, schema: serversSchema,
migrations: serversMigrations migrations: serversMigrations
}), }),
modelClasses: [Server, LoggedUser, ServersHistory], modelClasses: [Server, LoggedUser, ServersHistory]
actionsEnabled: true
}) })
}; };
@ -117,8 +115,7 @@ class DB {
FrequentlyUsedEmoji, FrequentlyUsedEmoji,
Setting, Setting,
User User
], ]
actionsEnabled: true
}); });
} }

View File

@ -18,6 +18,10 @@ const PERMISSIONS = [
'archive-room', 'archive-room',
'auto-translate', 'auto-translate',
'create-invite-links', 'create-invite-links',
'create-c',
'create-p',
'create-d',
'start-discussion',
'create-team', 'create-team',
'delete-c', 'delete-c',
'delete-message', 'delete-message',

View File

@ -1380,17 +1380,19 @@ const RocketChat = {
* Returns an array of boolean for each permission from permissions arg * Returns an array of boolean for each permission from permissions arg
*/ */
async hasPermission(permissions, rid) { async hasPermission(permissions, rid) {
const db = database.active;
const subsCollection = db.get('subscriptions');
let roomRoles = []; let roomRoles = [];
try { if (rid) {
// get the room from database const db = database.active;
const room = await subsCollection.find(rid); const subsCollection = db.get('subscriptions');
// get room roles try {
roomRoles = room.roles || []; // get the room from database
} catch (error) { const room = await subsCollection.find(rid);
console.log('hasPermission -> Room not found'); // get room roles
return permissions.map(() => false); roomRoles = room.roles || [];
} catch (error) {
console.log('hasPermission -> Room not found');
return permissions.map(() => false);
}
} }
try { try {
@ -1537,11 +1539,13 @@ const RocketChat = {
messageId messageId
}); });
}, },
searchMessages(roomId, searchText) { searchMessages(roomId, searchText, count, offset) {
// RC 0.60.0 // RC 0.60.0
return this.sdk.get('chat.search', { return this.sdk.get('chat.search', {
roomId, roomId,
searchText searchText,
count,
offset
}); });
}, },
toggleFollowMessage(mid, follow) { toggleFollowMessage(mid, follow) {

View File

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import { StyleSheet, View } from 'react-native'; import { StyleSheet, View } from 'react-native';
import { PanGestureHandler, PinchGestureHandler, State } from 'react-native-gesture-handler'; import { PanGestureHandler, PinchGestureHandler, State } from 'react-native-gesture-handler';
import Animated, { Easing } from 'react-native-reanimated'; import Animated, { EasingNode } from 'react-native-reanimated';
import { ImageComponent } from './ImageComponent'; import { ImageComponent } from './ImageComponent';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
@ -94,7 +94,7 @@ function runTiming(clock: any, value: any, dest: any, startStopClock: any = true
const config = { const config = {
toValue: new Value(0), toValue: new Value(0),
duration: 300, duration: 300,
easing: Easing.inOut(Easing.cubic) easing: EasingNode.inOut(EasingNode.cubic)
}; };
return [ return [
@ -215,7 +215,9 @@ class Image extends React.PureComponent<IImageProps, any> {
return <Component {...this.props} />; return <Component {...this.props} />;
} }
} }
const AnimatedImage = Animated.createAnimatedComponent(Image);
// https://github.com/software-mansion/react-native-reanimated/issues/1717
const AnimatedImage: any = Animated.createAnimatedComponent(Image);
// it was picked from https://github.com/software-mansion/react-native-reanimated/tree/master/Example/imageViewer // it was picked from https://github.com/software-mansion/react-native-reanimated/tree/master/Example/imageViewer
// and changed to use FastImage animated component // and changed to use FastImage animated component

View File

@ -1,11 +1,12 @@
import React from 'react'; import React from 'react';
import { Animated, Text, View } from 'react-native'; import { Animated, View } from 'react-native';
import { RectButton } from 'react-native-gesture-handler'; import { RectButton } from 'react-native-gesture-handler';
import I18n, { isRTL } from '../../i18n'; import { isRTL } from '../../i18n';
import styles, { ACTION_WIDTH, LONG_SWIPE } from './styles';
import { CustomIcon } from '../../lib/Icons'; import { CustomIcon } from '../../lib/Icons';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import { DISPLAY_MODE_CONDENSED } from '../../constants/constantDisplayMode';
import styles, { ACTION_WIDTH, LONG_SWIPE, ROW_HEIGHT_CONDENSED } from './styles';
interface ILeftActions { interface ILeftActions {
theme: string; theme: string;
@ -13,6 +14,7 @@ interface ILeftActions {
isRead: boolean; isRead: boolean;
width: number; width: number;
onToggleReadPress(): void; onToggleReadPress(): void;
displayMode: string;
} }
interface IRightActions { interface IRightActions {
@ -22,11 +24,14 @@ interface IRightActions {
width: number; width: number;
toggleFav(): void; toggleFav(): void;
onHidePress(): void; onHidePress(): void;
displayMode: string;
} }
const reverse = new Animated.Value(isRTL() ? -1 : 1); const reverse = new Animated.Value(isRTL() ? -1 : 1);
const CONDENSED_ICON_SIZE = 24;
const EXPANDED_ICON_SIZE = 28;
export const LeftActions = React.memo(({ theme, transX, isRead, width, onToggleReadPress }: ILeftActions) => { export const LeftActions = React.memo(({ theme, transX, isRead, width, onToggleReadPress, displayMode }: ILeftActions) => {
const translateX = Animated.multiply( const translateX = Animated.multiply(
transX.interpolate({ transX.interpolate({
inputRange: [0, ACTION_WIDTH], inputRange: [0, ACTION_WIDTH],
@ -34,6 +39,10 @@ export const LeftActions = React.memo(({ theme, transX, isRead, width, onToggleR
}), }),
reverse reverse
); );
const isCondensed = displayMode === DISPLAY_MODE_CONDENSED;
const viewHeight = isCondensed ? { height: ROW_HEIGHT_CONDENSED } : null;
return ( return (
<View style={[styles.actionsContainer, styles.actionLeftContainer]} pointerEvents='box-none'> <View style={[styles.actionsContainer, styles.actionLeftContainer]} pointerEvents='box-none'>
<Animated.View <Animated.View
@ -44,14 +53,16 @@ export const LeftActions = React.memo(({ theme, transX, isRead, width, onToggleR
width, width,
transform: [{ translateX }], transform: [{ translateX }],
backgroundColor: themes[theme].tintColor backgroundColor: themes[theme].tintColor
} },
viewHeight
]}> ]}>
<View style={styles.actionLeftButtonContainer}> <View style={[styles.actionLeftButtonContainer, viewHeight]}>
<RectButton style={styles.actionButton} onPress={onToggleReadPress}> <RectButton style={styles.actionButton} onPress={onToggleReadPress}>
<> <CustomIcon
<CustomIcon size={20} name={isRead ? 'flag' : 'check'} color='white' /> size={isCondensed ? CONDENSED_ICON_SIZE : EXPANDED_ICON_SIZE}
<Text style={[styles.actionText, { color: themes[theme].buttonText }]}>{I18n.t(isRead ? 'Unread' : 'Read')}</Text> name={isRead ? 'flag' : 'check'}
</> color={themes[theme].buttonText}
/>
</RectButton> </RectButton>
</View> </View>
</Animated.View> </Animated.View>
@ -59,64 +70,64 @@ export const LeftActions = React.memo(({ theme, transX, isRead, width, onToggleR
); );
}); });
export const RightActions = React.memo(({ transX, favorite, width, toggleFav, onHidePress, theme }: IRightActions) => { export const RightActions = React.memo(
const translateXFav = Animated.multiply( ({ transX, favorite, width, toggleFav, onHidePress, theme, displayMode }: IRightActions) => {
transX.interpolate({ const translateXFav = Animated.multiply(
inputRange: [-width / 2, -ACTION_WIDTH * 2, 0], transX.interpolate({
outputRange: [width / 2, width - ACTION_WIDTH * 2, width] inputRange: [-width / 2, -ACTION_WIDTH * 2, 0],
}), outputRange: [width / 2, width - ACTION_WIDTH * 2, width]
reverse }),
); reverse
const translateXHide = Animated.multiply( );
transX.interpolate({ const translateXHide = Animated.multiply(
inputRange: [-width, -LONG_SWIPE, -ACTION_WIDTH * 2, 0], transX.interpolate({
outputRange: [0, width - LONG_SWIPE, width - ACTION_WIDTH, width] inputRange: [-width, -LONG_SWIPE, -ACTION_WIDTH * 2, 0],
}), outputRange: [0, width - LONG_SWIPE, width - ACTION_WIDTH, width]
reverse }),
); reverse
return ( );
<View
style={{ const isCondensed = displayMode === DISPLAY_MODE_CONDENSED;
position: 'absolute', const viewHeight = isCondensed ? { height: ROW_HEIGHT_CONDENSED } : null;
left: 0,
right: 0, return (
height: 75, <View style={[styles.actionsLeftContainer, viewHeight]} pointerEvents='box-none'>
flexDirection: 'row' <Animated.View
}} style={[
pointerEvents='box-none'> styles.actionRightButtonContainer,
<Animated.View {
style={[ width,
styles.actionRightButtonContainer, transform: [{ translateX: translateXFav }],
{ backgroundColor: themes[theme].hideBackground
width, },
transform: [{ translateX: translateXFav }], viewHeight
backgroundColor: themes[theme].hideBackground ]}>
} <RectButton style={[styles.actionButton, { backgroundColor: themes[theme].favoriteBackground }]} onPress={toggleFav}>
]}> <CustomIcon
<RectButton style={[styles.actionButton, { backgroundColor: themes[theme].favoriteBackground }]} onPress={toggleFav}> size={isCondensed ? CONDENSED_ICON_SIZE : EXPANDED_ICON_SIZE}
<> name={favorite ? 'star-filled' : 'star'}
<CustomIcon size={20} name={favorite ? 'star-filled' : 'star'} color={themes[theme].buttonText} /> color={themes[theme].buttonText}
<Text style={[styles.actionText, { color: themes[theme].buttonText }]}> />
{I18n.t(favorite ? 'Unfavorite' : 'Favorite')} </RectButton>
</Text> </Animated.View>
</> <Animated.View
</RectButton> style={[
</Animated.View> styles.actionRightButtonContainer,
<Animated.View {
style={[ width,
styles.actionRightButtonContainer, transform: [{ translateX: translateXHide }]
{ },
width, isCondensed && { height: ROW_HEIGHT_CONDENSED }
transform: [{ translateX: translateXHide }] ]}>
} <RectButton style={[styles.actionButton, { backgroundColor: themes[theme].hideBackground }]} onPress={onHidePress}>
]}> <CustomIcon
<RectButton style={[styles.actionButton, { backgroundColor: themes[theme].hideBackground }]} onPress={onHidePress}> size={isCondensed ? CONDENSED_ICON_SIZE : EXPANDED_ICON_SIZE}
<> name='unread-on-top-disabled'
<CustomIcon size={20} name='unread-on-top-disabled' color={themes[theme].buttonText} /> color={themes[theme].buttonText}
<Text style={[styles.actionText, { color: themes[theme].buttonText }]}>{I18n.t('Hide')}</Text> />
</> </RectButton>
</RectButton> </Animated.View>
</Animated.View> </View>
</View> );
); }
}); );

View File

@ -0,0 +1,63 @@
import React from 'react';
import { View } from 'react-native';
import PropTypes from 'prop-types';
import Avatar from '../../containers/Avatar';
import { DISPLAY_MODE_CONDENSED, DISPLAY_MODE_EXPANDED } from '../../constants/constantDisplayMode';
import TypeIcon from './TypeIcon';
import styles from './styles';
const IconOrAvatar = ({
avatar,
type,
rid,
showAvatar,
prid,
status,
isGroupChat,
teamMain,
showLastMessage,
theme,
displayMode
}) => {
if (showAvatar) {
return (
<Avatar text={avatar} size={displayMode === DISPLAY_MODE_CONDENSED ? 36 : 48} type={type} style={styles.avatar} rid={rid} />
);
}
if (displayMode === DISPLAY_MODE_EXPANDED && showLastMessage) {
return (
<View style={styles.typeIcon}>
<TypeIcon
type={type}
prid={prid}
status={status}
isGroupChat={isGroupChat}
theme={theme}
teamMain={teamMain}
size={24}
style={{ marginRight: 12 }}
/>
</View>
);
}
return null;
};
IconOrAvatar.propTypes = {
avatar: PropTypes.string,
type: PropTypes.string,
theme: PropTypes.string,
rid: PropTypes.string,
showAvatar: PropTypes.bool,
displayMode: PropTypes.string,
prid: PropTypes.string,
status: PropTypes.string,
isGroupChat: PropTypes.bool,
teamMain: PropTypes.bool,
showLastMessage: PropTypes.bool
};
export default IconOrAvatar;

View File

@ -80,6 +80,7 @@ const LastMessage = React.memo(
numberOfLines={2} numberOfLines={2}
preview preview
theme={theme} theme={theme}
testID='room-item-last-message'
/> />
), ),
arePropsEqual arePropsEqual

View File

@ -11,6 +11,7 @@ import UpdatedAt from './UpdatedAt';
import Touchable from './Touchable'; import Touchable from './Touchable';
import Tag from './Tag'; import Tag from './Tag';
import I18n from '../../i18n'; import I18n from '../../i18n';
import { DISPLAY_MODE_EXPANDED } from '../../constants/constantDisplayMode';
interface IRoomItem { interface IRoomItem {
rid: string; rid: string;
@ -57,6 +58,8 @@ interface IRoomItem {
hideChannel(): void; hideChannel(): void;
autoJoin: boolean; autoJoin: boolean;
size?: number; size?: number;
showAvatar: boolean;
displayMode: string;
} }
const RoomItem = ({ const RoomItem = ({
@ -95,7 +98,9 @@ const RoomItem = ({
toggleRead, toggleRead,
hideChannel, hideChannel,
teamMain, teamMain,
autoJoin autoJoin,
showAvatar,
displayMode
}: IRoomItem) => ( }: IRoomItem) => (
<Touchable <Touchable
onPress={onPress} onPress={onPress}
@ -111,12 +116,28 @@ const RoomItem = ({
type={type} type={type}
theme={theme} theme={theme}
isFocused={isFocused} isFocused={isFocused}
swipeEnabled={swipeEnabled}> swipeEnabled={swipeEnabled}
<Wrapper accessibilityLabel={accessibilityLabel} avatar={avatar} avatarSize={avatarSize} type={type} theme={theme} rid={rid}> displayMode={displayMode}>
{showLastMessage ? ( <Wrapper
accessibilityLabel={accessibilityLabel}
avatar={avatar}
avatarSize={avatarSize}
type={type}
theme={theme}
rid={rid}
prid={prid}
status={status}
isGroupChat={isGroupChat}
teamMain={teamMain}
displayMode={displayMode}
showAvatar={showAvatar}
showLastMessage={showLastMessage}>
{showLastMessage && displayMode === DISPLAY_MODE_EXPANDED ? (
<> <>
<View style={styles.titleContainer}> <View style={styles.titleContainer}>
<TypeIcon type={type} prid={prid} status={status} isGroupChat={isGroupChat} theme={theme} teamMain={teamMain} /> {showAvatar ? (
<TypeIcon type={type} prid={prid} status={status} isGroupChat={isGroupChat} theme={theme} teamMain={teamMain} />
) : null}
<Title name={name} theme={theme} hideUnreadStatus={hideUnreadStatus} alert={alert} /> <Title name={name} theme={theme} hideUnreadStatus={hideUnreadStatus} alert={alert} />
{autoJoin ? <Tag testID='auto-join-tag' name={I18n.t('Auto-join')} /> : null} {autoJoin ? <Tag testID='auto-join-tag' name={I18n.t('Auto-join')} /> : null}
<UpdatedAt date={date} theme={theme} hideUnreadStatus={hideUnreadStatus} alert={alert} /> <UpdatedAt date={date} theme={theme} hideUnreadStatus={hideUnreadStatus} alert={alert} />
@ -143,17 +164,29 @@ const RoomItem = ({
</> </>
) : ( ) : (
<View style={[styles.titleContainer, styles.flex]}> <View style={[styles.titleContainer, styles.flex]}>
<TypeIcon type={type} prid={prid} status={status} isGroupChat={isGroupChat} theme={theme} teamMain={teamMain} /> <TypeIcon
type={type}
prid={prid}
status={status}
isGroupChat={isGroupChat}
theme={theme}
teamMain={teamMain}
size={22}
style={{ marginRight: 8 }}
/>
<Title name={name} theme={theme} hideUnreadStatus={hideUnreadStatus} alert={alert} /> <Title name={name} theme={theme} hideUnreadStatus={hideUnreadStatus} alert={alert} />
{autoJoin ? <Tag name={I18n.t('Auto-join')} /> : null} {autoJoin ? <Tag name={I18n.t('Auto-join')} /> : null}
<UnreadBadge <View style={styles.wrapUpdatedAndBadge}>
unread={unread} <UpdatedAt date={date} theme={theme} hideUnreadStatus={hideUnreadStatus} alert={alert} />
userMentions={userMentions} <UnreadBadge
groupMentions={groupMentions} unread={unread}
tunread={tunread} userMentions={userMentions}
tunreadUser={tunreadUser} groupMentions={groupMentions}
tunreadGroup={tunreadGroup} tunread={tunread}
/> tunreadUser={tunreadUser}
tunreadGroup={tunreadGroup}
/>
</View>
</View> </View>
)} )}
</Wrapper> </Wrapper>

View File

@ -24,6 +24,7 @@ interface ITouchableProps {
theme: string; theme: string;
isFocused: boolean; isFocused: boolean;
swipeEnabled: boolean; swipeEnabled: boolean;
displayMode: string;
} }
class Touchable extends React.Component<ITouchableProps, any> { class Touchable extends React.Component<ITouchableProps, any> {
@ -227,7 +228,7 @@ class Touchable extends React.Component<ITouchableProps, any> {
}; };
render() { render() {
const { testID, isRead, width, favorite, children, theme, isFocused, swipeEnabled } = this.props; const { testID, isRead, width, favorite, children, theme, isFocused, swipeEnabled, displayMode } = this.props;
return ( return (
<LongPressGestureHandler onHandlerStateChange={this.onLongPressHandlerStateChange}> <LongPressGestureHandler onHandlerStateChange={this.onLongPressHandlerStateChange}>
@ -244,6 +245,7 @@ class Touchable extends React.Component<ITouchableProps, any> {
width={width} width={width}
onToggleReadPress={this.onToggleReadPress} onToggleReadPress={this.onToggleReadPress}
theme={theme} theme={theme}
displayMode={displayMode}
/> />
<RightActions <RightActions
transX={this.transXReverse} transX={this.transXReverse}
@ -252,6 +254,7 @@ class Touchable extends React.Component<ITouchableProps, any> {
toggleFav={this.toggleFav} toggleFav={this.toggleFav}
onHidePress={this.onHidePress} onHidePress={this.onHidePress}
theme={theme} theme={theme}
displayMode={displayMode}
/> />
<Animated.View <Animated.View
style={{ style={{

View File

@ -9,10 +9,19 @@ interface ITypeIcon {
isGroupChat: boolean; isGroupChat: boolean;
teamMain: boolean; teamMain: boolean;
theme?: string; theme?: string;
size?: number;
style?: object;
} }
const TypeIcon = React.memo(({ type, prid, status, isGroupChat, teamMain }: ITypeIcon) => ( const TypeIcon = React.memo(({ type, prid, status, isGroupChat, teamMain, size, style }: ITypeIcon) => (
<RoomTypeIcon type={prid ? 'discussion' : type} isGroupChat={isGroupChat} status={status} teamMain={teamMain} /> <RoomTypeIcon
type={prid ? 'discussion' : type}
isGroupChat={isGroupChat}
status={status}
teamMain={teamMain}
size={size}
style={style}
/>
)); ));
export default TypeIcon; export default TypeIcon;

View File

@ -1,9 +1,10 @@
import React from 'react'; import React from 'react';
import { View } from 'react-native'; import { View } from 'react-native';
import styles from './styles';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import Avatar from '../../containers/Avatar'; import { DISPLAY_MODE_CONDENSED } from '../../constants/constantDisplayMode';
import IconOrAvatar from './IconOrAvatar';
import styles from './styles';
interface IWrapper { interface IWrapper {
accessibilityLabel: string; accessibilityLabel: string;
@ -13,17 +14,27 @@ interface IWrapper {
theme: string; theme: string;
rid: string; rid: string;
children: JSX.Element; children: JSX.Element;
displayMode: string;
prid: string;
showLastMessage: boolean;
status: string;
isGroupChat: boolean;
teamMain: boolean;
showAvatar: boolean;
} }
const Wrapper = ({ accessibilityLabel, avatar, avatarSize, type, theme, rid, children }: IWrapper) => ( const Wrapper = ({ accessibilityLabel, theme, children, displayMode, ...props }: IWrapper) => (
<View style={styles.container} accessibilityLabel={accessibilityLabel}> <View
<Avatar text={avatar} size={avatarSize} type={type} style={styles.avatar} rid={rid} /> style={[styles.container, displayMode === DISPLAY_MODE_CONDENSED && styles.containerCondensed]}
accessibilityLabel={accessibilityLabel}>
<IconOrAvatar theme={theme} displayMode={displayMode} {...props} />
<View <View
style={[ style={[
styles.centerContainer, styles.centerContainer,
{ {
borderColor: themes[theme].separatorColor borderColor: themes[theme].separatorColor
} },
displayMode === DISPLAY_MODE_CONDENSED && styles.condensedPaddingVertical
]}> ]}>
{children} {children}
</View> </View>

View File

@ -2,12 +2,11 @@ import React from 'react';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import I18n from '../../i18n'; import I18n from '../../i18n';
import { ROW_HEIGHT } from './styles'; import { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from './styles';
import { formatDate } from '../../utils/room'; import { formatDate } from '../../utils/room';
import RoomItem from './RoomItem'; import RoomItem from './RoomItem';
export { ROW_HEIGHT }; export { ROW_HEIGHT, ROW_HEIGHT_CONDENSED };
interface IRoomItemContainerProps { interface IRoomItemContainerProps {
item: any; item: any;
showLastMessage: boolean; showLastMessage: boolean;
@ -32,9 +31,22 @@ interface IRoomItemContainerProps {
getIsRead: Function; getIsRead: Function;
swipeEnabled: boolean; swipeEnabled: boolean;
autoJoin: boolean; autoJoin: boolean;
showAvatar: boolean;
displayMode: string;
} }
const attrs = ['width', 'status', 'connected', 'theme', 'isFocused', 'forceUpdate', 'showLastMessage', 'autoJoin']; const attrs = [
'width',
'status',
'connected',
'theme',
'isFocused',
'forceUpdate',
'showLastMessage',
'autoJoin',
'showAvatar',
'displayMode'
];
class RoomItemContainer extends React.Component<IRoomItemContainerProps, any> { class RoomItemContainer extends React.Component<IRoomItemContainerProps, any> {
private mounted: boolean; private mounted: boolean;
@ -137,7 +149,9 @@ class RoomItemContainer extends React.Component<IRoomItemContainerProps, any> {
username, username,
useRealName, useRealName,
swipeEnabled, swipeEnabled,
autoJoin autoJoin,
showAvatar,
displayMode
} = this.props; } = this.props;
const name = getRoomTitle(item); const name = getRoomTitle(item);
const testID = `rooms-list-view-item-${name}`; const testID = `rooms-list-view-item-${name}`;
@ -200,6 +214,8 @@ class RoomItemContainer extends React.Component<IRoomItemContainerProps, any> {
swipeEnabled={swipeEnabled} swipeEnabled={swipeEnabled}
teamMain={item.teamMain} teamMain={item.teamMain}
autoJoin={autoJoin} autoJoin={autoJoin}
showAvatar={showAvatar}
displayMode={displayMode}
/> />
); );
} }

View File

@ -3,6 +3,7 @@ import { PixelRatio, StyleSheet } from 'react-native';
import sharedStyles from '../../views/Styles'; import sharedStyles from '../../views/Styles';
export const ROW_HEIGHT = 75 * PixelRatio.getFontScale(); export const ROW_HEIGHT = 75 * PixelRatio.getFontScale();
export const ROW_HEIGHT_CONDENSED = 60 * PixelRatio.getFontScale();
export const ACTION_WIDTH = 80; export const ACTION_WIDTH = 80;
export const SMALL_SWIPE = ACTION_WIDTH / 2; export const SMALL_SWIPE = ACTION_WIDTH / 2;
export const LONG_SWIPE = ACTION_WIDTH * 3; export const LONG_SWIPE = ACTION_WIDTH * 3;
@ -17,6 +18,12 @@ export default StyleSheet.create<any>({
paddingLeft: 14, paddingLeft: 14,
height: ROW_HEIGHT height: ROW_HEIGHT
}, },
containerCondensed: {
height: ROW_HEIGHT_CONDENSED
},
condensedPaddingVertical: {
paddingVertical: 20
},
centerContainer: { centerContainer: {
flex: 1, flex: 1,
paddingVertical: 10, paddingVertical: 10,
@ -37,6 +44,9 @@ export default StyleSheet.create<any>({
flexDirection: 'row', flexDirection: 'row',
alignItems: 'flex-start' alignItems: 'flex-start'
}, },
wrapUpdatedAndBadge: {
alignItems: 'flex-end'
},
titleContainer: { titleContainer: {
width: '100%', width: '100%',
flexDirection: 'row', flexDirection: 'row',
@ -72,11 +82,12 @@ export default StyleSheet.create<any>({
right: 0, right: 0,
height: ROW_HEIGHT height: ROW_HEIGHT
}, },
actionText: { actionsLeftContainer: {
fontSize: 15, flexDirection: 'row',
justifyContent: 'center', position: 'absolute',
marginTop: 4, left: 0,
...sharedStyles.textSemibold right: 0,
height: ROW_HEIGHT
}, },
actionLeftButtonContainer: { actionLeftButtonContainer: {
position: 'absolute', position: 'absolute',
@ -107,5 +118,9 @@ export default StyleSheet.create<any>({
fontSize: 13, fontSize: 13,
paddingHorizontal: 4, paddingHorizontal: 4,
...sharedStyles.textSemibold ...sharedStyles.textSemibold
},
typeIcon: {
height: ROW_HEIGHT,
justifyContent: 'center'
} }
}); });

View File

@ -8,7 +8,6 @@ const initialState = {
searchText: '', searchText: '',
showServerDropdown: false, showServerDropdown: false,
closeServerDropdown: false, closeServerDropdown: false,
showSortDropdown: false,
showSearchHeader: false showSearchHeader: false
}; };
@ -56,16 +55,6 @@ export default function login(state = initialState, action) {
...state, ...state,
showServerDropdown: !state.showServerDropdown showServerDropdown: !state.showServerDropdown
}; };
case types.ROOMS.CLOSE_SORT_DROPDOWN:
return {
...state,
closeSortDropdown: !state.closeSortDropdown
};
case types.ROOMS.TOGGLE_SORT_DROPDOWN:
return {
...state,
showSortDropdown: !state.showSortDropdown
};
case types.ROOMS.OPEN_SEARCH_HEADER: case types.ROOMS.OPEN_SEARCH_HEADER:
return { return {
...state, ...state,

View File

@ -1,10 +1,13 @@
import { SORT_PREFERENCES } from '../actions/actionsTypes'; import { SORT_PREFERENCES } from '../actions/actionsTypes';
import { DISPLAY_MODE_EXPANDED } from '../constants/constantDisplayMode';
const initialState = { const initialState = {
sortBy: 'activity', sortBy: 'activity',
groupByType: false, groupByType: false,
showFavorites: false, showFavorites: false,
showUnread: false showUnread: false,
showAvatar: true,
displayMode: DISPLAY_MODE_EXPANDED
}; };
export default (state = initialState, action) => { export default (state = initialState, action) => {

View File

@ -38,6 +38,9 @@ import ProfileView from '../views/ProfileView';
import UserPreferencesView from '../views/UserPreferencesView'; import UserPreferencesView from '../views/UserPreferencesView';
import UserNotificationPrefView from '../views/UserNotificationPreferencesView'; import UserNotificationPrefView from '../views/UserNotificationPreferencesView';
// Display Preferences View
import DisplayPrefsView from '../views/DisplayPrefsView';
// Settings Stack // Settings Stack
import SettingsView from '../views/SettingsView'; import SettingsView from '../views/SettingsView';
import SecurityPrivacyView from '../views/SecurityPrivacyView'; import SecurityPrivacyView from '../views/SecurityPrivacyView';
@ -220,6 +223,18 @@ const AdminPanelStackNavigator = () => {
); );
}; };
// DisplayPreferenceNavigator
const DisplayPrefStack = createStackNavigator();
const DisplayPrefStackNavigator = () => {
const { theme } = React.useContext(ThemeContext);
return (
<DisplayPrefStack.Navigator screenOptions={{ ...defaultHeader, ...themedHeader(theme), ...StackAnimation }}>
<DisplayPrefStack.Screen name='DisplayPrefsView' component={DisplayPrefsView} />
</DisplayPrefStack.Navigator>
);
};
// DrawerNavigator // DrawerNavigator
const Drawer = createDrawerNavigator(); const Drawer = createDrawerNavigator();
const DrawerNavigator = () => { const DrawerNavigator = () => {
@ -236,6 +251,7 @@ const DrawerNavigator = () => {
<Drawer.Screen name='ProfileStackNavigator' component={ProfileStackNavigator} /> <Drawer.Screen name='ProfileStackNavigator' component={ProfileStackNavigator} />
<Drawer.Screen name='SettingsStackNavigator' component={SettingsStackNavigator} /> <Drawer.Screen name='SettingsStackNavigator' component={SettingsStackNavigator} />
<Drawer.Screen name='AdminPanelStackNavigator' component={AdminPanelStackNavigator} /> <Drawer.Screen name='AdminPanelStackNavigator' component={AdminPanelStackNavigator} />
<Drawer.Screen name='DisplayPrefStackNavigator' component={DisplayPrefStackNavigator} />
</Drawer.Navigator> </Drawer.Navigator>
); );
}; };

View File

@ -33,6 +33,7 @@ import TeamChannelsView from '../../views/TeamChannelsView';
import MarkdownTableView from '../../views/MarkdownTableView'; import MarkdownTableView from '../../views/MarkdownTableView';
import ReadReceiptsView from '../../views/ReadReceiptView'; import ReadReceiptsView from '../../views/ReadReceiptView';
import ProfileView from '../../views/ProfileView'; import ProfileView from '../../views/ProfileView';
import DisplayPrefsView from '../../views/DisplayPrefsView';
import SettingsView from '../../views/SettingsView'; import SettingsView from '../../views/SettingsView';
import LanguageView from '../../views/LanguageView'; import LanguageView from '../../views/LanguageView';
import ThemeView from '../../views/ThemeView'; import ThemeView from '../../views/ThemeView';
@ -204,6 +205,7 @@ const ModalStackNavigator = React.memo(({ navigation }) => {
component={ProfileView} component={ProfileView}
options={props => ProfileView.navigationOptions({ ...props, isMasterDetail: true })} options={props => ProfileView.navigationOptions({ ...props, isMasterDetail: true })}
/> />
<ModalStack.Screen name='DisplayPrefsView' component={DisplayPrefsView} />
<ModalStack.Screen <ModalStack.Screen
name='AdminPanelView' name='AdminPanelView'
component={AdminPanelView} component={AdminPanelView}

View File

@ -66,15 +66,18 @@ export default {
RL_TOGGLE_READ_F: 'rl_toggle_read_f', RL_TOGGLE_READ_F: 'rl_toggle_read_f',
RL_HIDE_CHANNEL: 'rl_hide_channel', RL_HIDE_CHANNEL: 'rl_hide_channel',
RL_HIDE_CHANNEL_F: 'rl_hide_channel_f', RL_HIDE_CHANNEL_F: 'rl_hide_channel_f',
RL_TOGGLE_SORT_DROPDOWN: 'rl_toggle_sort_dropdown',
RL_SORT_CHANNELS_BY_NAME: 'rl_sort_channels_by_name',
RL_SORT_CHANNELS_BY_ACTIVITY: 'rl_sort_channels_by_activity',
RL_SORT_CHANNELS_F: 'rl_sort_channels_f',
RL_GROUP_CHANNELS_BY_TYPE: 'rl_group_channels_by_type',
RL_GROUP_CHANNELS_BY_FAVORITE: 'rl_group_channels_by_favorite',
RL_GROUP_CHANNELS_BY_UNREAD: 'rl_group_channels_by_unread',
RL_CREATE_NEW_WORKSPACE: 'rl_create_new_workspace', RL_CREATE_NEW_WORKSPACE: 'rl_create_new_workspace',
// DISPLAY PREFERENCES VIEW
DP_SORT_CHANNELS_BY_NAME: 'dp_sort_channels_by_name',
DP_SORT_CHANNELS_BY_ACTIVITY: 'dp_sort_channels_by_activity',
DP_GROUP_CHANNELS_BY_TYPE: 'dp_group_channels_by_type',
DP_GROUP_CHANNELS_BY_FAVORITE: 'dp_group_channels_by_favorite',
DP_GROUP_CHANNELS_BY_UNREAD: 'dp_group_channels_by_unread',
DP_TOGGLE_AVATAR: 'dp_toggle_avatar',
DP_DISPLAY_EXPANDED: 'dp_display_expanded',
DP_DISPLAY_CONDENSED: 'dp_display_condensed',
// QUEUE LIST VIEW // QUEUE LIST VIEW
QL_GO_ROOM: 'ql_go_room', QL_GO_ROOM: 'ql_go_room',

View File

@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { ActivityIndicator, StyleSheet, Text, View } from 'react-native'; import { ActivityIndicator, StyleSheet, Text, View } from 'react-native';
import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import I18n from '../i18n'; import I18n from '../i18n';
@ -23,25 +22,25 @@ const styles = StyleSheet.create({
} }
}); });
const AuthLoadingView = React.memo(({ theme, text }) => ( interface IAuthLoadingView {
theme: string;
text: string;
}
const AuthLoadingView = React.memo(({ theme, text }: IAuthLoadingView) => (
<View style={[styles.container, { backgroundColor: themes[theme].backgroundColor }]}> <View style={[styles.container, { backgroundColor: themes[theme].backgroundColor }]}>
<StatusBar /> <StatusBar />
{text && ( {text ? (
<> <>
<ActivityIndicator color={themes[theme].auxiliaryText} size='large' /> <ActivityIndicator color={themes[theme].auxiliaryText} size='large' />
<Text style={[styles.text, { color: themes[theme].bodyText }]}>{`${text}\n${I18n.t('Please_wait')}`}</Text> <Text style={[styles.text, { color: themes[theme].bodyText }]}>{`${text}\n${I18n.t('Please_wait')}`}</Text>
</> </>
)} ) : null}
</View> </View>
)); ));
const mapStateToProps = state => ({ const mapStateToProps = (state: any) => ({
text: state.app.text text: state.app.text
}); });
AuthLoadingView.propTypes = {
theme: PropTypes.string,
text: PropTypes.string
};
export default connect(mapStateToProps)(withTheme(AuthLoadingView)); export default connect(mapStateToProps)(withTheme(AuthLoadingView));

View File

@ -21,6 +21,7 @@ import { Review } from '../utils/review';
import { getUserSelector } from '../selectors/login'; import { getUserSelector } from '../selectors/login';
import { events, logEvent } from '../utils/log'; import { events, logEvent } from '../utils/log';
import SafeAreaView from '../containers/SafeAreaView'; import SafeAreaView from '../containers/SafeAreaView';
import RocketChat from '../lib/rocketchat';
import sharedStyles from './Styles'; import sharedStyles from './Styles';
const styles = StyleSheet.create({ const styles = StyleSheet.create({
@ -79,10 +80,13 @@ class CreateChannelView extends React.Component {
users: PropTypes.array.isRequired, users: PropTypes.array.isRequired,
user: PropTypes.shape({ user: PropTypes.shape({
id: PropTypes.string, id: PropTypes.string,
token: PropTypes.string token: PropTypes.string,
roles: PropTypes.array
}), }),
theme: PropTypes.string, theme: PropTypes.string,
teamId: PropTypes.string teamId: PropTypes.string,
createPublicChannelPermission: PropTypes.array,
createPrivateChannelPermission: PropTypes.array
}; };
constructor(props) { constructor(props) {
@ -96,14 +100,20 @@ class CreateChannelView extends React.Component {
readOnly: false, readOnly: false,
encrypted: false, encrypted: false,
broadcast: false, broadcast: false,
isTeam isTeam,
permissions: []
}; };
this.setHeader(); this.setHeader();
} }
componentDidMount() {
this.handleHasPermission();
}
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
const { channelName, type, readOnly, broadcast, encrypted } = this.state; const { channelName, type, readOnly, broadcast, encrypted, permissions } = this.state;
const { users, isFetching, encryptionEnabled, theme } = this.props; const { users, isFetching, encryptionEnabled, theme, createPublicChannelPermission, createPrivateChannelPermission } =
this.props;
if (nextProps.theme !== theme) { if (nextProps.theme !== theme) {
return true; return true;
} }
@ -122,18 +132,37 @@ class CreateChannelView extends React.Component {
if (nextState.broadcast !== broadcast) { if (nextState.broadcast !== broadcast) {
return true; return true;
} }
if (nextState.permissions !== permissions) {
return true;
}
if (nextProps.isFetching !== isFetching) { if (nextProps.isFetching !== isFetching) {
return true; return true;
} }
if (nextProps.encryptionEnabled !== encryptionEnabled) { if (nextProps.encryptionEnabled !== encryptionEnabled) {
return true; return true;
} }
if (!dequal(nextProps.createPublicChannelPermission, createPublicChannelPermission)) {
return true;
}
if (!dequal(nextProps.createPrivateChannelPermission, createPrivateChannelPermission)) {
return true;
}
if (!dequal(nextProps.users, users)) { if (!dequal(nextProps.users, users)) {
return true; return true;
} }
return false; return false;
} }
componentDidUpdate(prevProps) {
const { createPublicChannelPermission, createPrivateChannelPermission } = this.props;
if (
!dequal(createPublicChannelPermission, prevProps.createPublicChannelPermission) ||
!dequal(createPrivateChannelPermission, prevProps.createPrivateChannelPermission)
) {
this.handleHasPermission();
}
}
setHeader = () => { setHeader = () => {
const { navigation } = this.props; const { navigation } = this.props;
const { isTeam } = this.state; const { isTeam } = this.state;
@ -208,12 +237,21 @@ class CreateChannelView extends React.Component {
); );
}; };
handleHasPermission = async () => {
const { createPublicChannelPermission, createPrivateChannelPermission } = this.props;
const permissions = [createPublicChannelPermission, createPrivateChannelPermission];
const permissionsToCreate = await RocketChat.hasPermission(permissions);
this.setState({ permissions: permissionsToCreate });
};
renderType() { renderType() {
const { type, isTeam } = this.state; const { type, isTeam, permissions } = this.state;
const isDisabled = permissions.filter(r => r === true).length <= 1;
return this.renderSwitch({ return this.renderSwitch({
id: 'type', id: 'type',
value: type, value: permissions[1] ? type : false,
disabled: isDisabled,
label: isTeam ? 'Private_Team' : 'Private_Channel', label: isTeam ? 'Private_Team' : 'Private_Channel',
onValueChange: value => { onValueChange: value => {
logEvent(events.CR_TOGGLE_TYPE); logEvent(events.CR_TOGGLE_TYPE);
@ -373,7 +411,9 @@ const mapStateToProps = state => ({
isFetching: state.createChannel.isFetching, isFetching: state.createChannel.isFetching,
encryptionEnabled: state.encryption.enabled, encryptionEnabled: state.encryption.enabled,
users: state.selectedUsers.users, users: state.selectedUsers.users,
user: getUserSelector(state) user: getUserSelector(state),
createPublicChannelPermission: state.permissions['create-c'],
createPrivateChannelPermission: state.permissions['create-p']
}); });
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({

View File

@ -0,0 +1,192 @@
import React, { useEffect } from 'react';
import PropTypes from 'prop-types';
import { Switch } from 'react-native';
import { RadioButton } from 'react-native-ui-lib';
import { useDispatch, useSelector } from 'react-redux';
import { setPreference } from '../actions/sortPreferences';
import RocketChat from '../lib/rocketchat';
import StatusBar from '../containers/StatusBar';
import I18n from '../i18n';
import * as List from '../containers/List';
import { useTheme } from '../theme';
import { themes } from '../constants/colors';
import * as HeaderButton from '../containers/HeaderButton';
import SafeAreaView from '../containers/SafeAreaView';
import { ICON_SIZE } from '../containers/List/constants';
import log, { events, logEvent } from '../utils/log';
import { DISPLAY_MODE_CONDENSED, DISPLAY_MODE_EXPANDED } from '../constants/constantDisplayMode';
const DisplayPrefsView = props => {
const { theme } = useTheme();
const { sortBy, groupByType, showFavorites, showUnread, showAvatar, displayMode } = useSelector(state => state.sortPreferences);
const dispatch = useDispatch();
useEffect(() => {
const { navigation, isMasterDetail } = props;
navigation.setOptions({
title: I18n.t('Display'),
headerLeft: () =>
isMasterDetail ? (
<HeaderButton.CloseModal navigation={navigation} testID='display-view-close' />
) : (
<HeaderButton.Drawer navigation={navigation} testID='display-view-drawer' />
)
});
}, []);
const setSortPreference = async param => {
try {
dispatch(setPreference(param));
await RocketChat.saveSortPreference(param);
} catch (e) {
log(e);
}
};
const sortByName = async () => {
logEvent(events.DP_SORT_CHANNELS_BY_NAME);
await setSortPreference({ sortBy: 'alphabetical' });
};
const sortByActivity = async () => {
logEvent(events.DP_SORT_CHANNELS_BY_ACTIVITY);
await setSortPreference({ sortBy: 'activity' });
};
const toggleGroupByType = async () => {
logEvent(events.DP_GROUP_CHANNELS_BY_TYPE);
await setSortPreference({ groupByType: !groupByType });
};
const toggleGroupByFavorites = async () => {
logEvent(events.DP_GROUP_CHANNELS_BY_FAVORITE);
await setSortPreference({ showFavorites: !showFavorites });
};
const toggleUnread = async () => {
logEvent(events.DP_GROUP_CHANNELS_BY_UNREAD);
await setSortPreference({ showUnread: !showUnread });
};
const toggleAvatar = async () => {
logEvent(events.DP_TOGGLE_AVATAR);
await setSortPreference({ showAvatar: !showAvatar });
};
const displayExpanded = async () => {
logEvent(events.DP_DISPLAY_EXPANDED);
await setSortPreference({ displayMode: DISPLAY_MODE_EXPANDED });
};
const displayCondensed = async () => {
logEvent(events.DP_DISPLAY_CONDENSED);
await setSortPreference({ displayMode: DISPLAY_MODE_CONDENSED });
};
const renderCheckBox = value => (
<List.Icon name={value ? 'checkbox-checked' : 'checkbox-unchecked'} color={value ? themes[theme].actionTintColor : null} />
);
const renderAvatarSwitch = value => (
<Switch value={value} onValueChange={() => toggleAvatar()} testID='display-pref-view-avatar-switch' />
);
const renderRadio = value => (
<RadioButton
selected={!!value}
color={value ? themes[theme].actionTintColor : themes[theme].auxiliaryText}
size={ICON_SIZE}
/>
);
return (
<SafeAreaView>
<StatusBar />
<List.Container testID='display-view-list'>
<List.Section title='Display'>
<List.Separator />
<List.Item
left={() => <List.Icon name='view-extended' />}
title='Expanded'
testID='display-pref-view-expanded'
right={() => renderRadio(displayMode === DISPLAY_MODE_EXPANDED)}
onPress={displayExpanded}
/>
<List.Separator />
<List.Item
left={() => <List.Icon name='view-medium' />}
title='Condensed'
testID='display-pref-view-condensed'
right={() => renderRadio(displayMode === DISPLAY_MODE_CONDENSED)}
onPress={displayCondensed}
/>
<List.Separator />
<List.Item
left={() => <List.Icon name='avatar' />}
title='Avatars'
testID='display-pref-view-avatars'
right={() => renderAvatarSwitch(showAvatar)}
/>
<List.Separator />
</List.Section>
<List.Section title='Sort_by'>
<List.Separator />
<List.Item
title='Activity'
testID='display-pref-view-activity'
left={() => <List.Icon name='clock' />}
onPress={sortByActivity}
right={() => renderRadio(sortBy === 'activity')}
/>
<List.Separator />
<List.Item
title='Name'
testID='display-pref-view-name'
left={() => <List.Icon name='sort-az' />}
onPress={sortByName}
right={() => renderRadio(sortBy === 'alphabetical')}
/>
<List.Separator />
</List.Section>
<List.Section title='Group_by'>
<List.Separator />
<List.Item
title='Unread_on_top'
testID='display-pref-view-unread'
left={() => <List.Icon name='flag' />}
onPress={toggleUnread}
right={() => renderCheckBox(showUnread)}
/>
<List.Separator />
<List.Item
title='Favorites'
testID='display-pref-view-favorites'
left={() => <List.Icon name='star' />}
onPress={toggleGroupByFavorites}
right={() => renderCheckBox(showFavorites)}
/>
<List.Separator />
<List.Item
title='Types'
testID='display-pref-view-types'
left={() => <List.Icon name='group-by-type' />}
onPress={toggleGroupByType}
right={() => renderCheckBox(groupByType)}
/>
<List.Separator />
</List.Section>
</List.Container>
</SafeAreaView>
);
};
DisplayPrefsView.propTypes = {
navigation: PropTypes.object,
isMasterDetail: PropTypes.bool
};
export default DisplayPrefsView;

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { StackNavigationOptions } from '@react-navigation/stack';
import I18n from '../i18n'; import I18n from '../i18n';
import StatusBar from '../containers/StatusBar'; import StatusBar from '../containers/StatusBar';
@ -9,13 +9,17 @@ import { withTheme } from '../theme';
import SafeAreaView from '../containers/SafeAreaView'; import SafeAreaView from '../containers/SafeAreaView';
import * as List from '../containers/List'; import * as List from '../containers/List';
class LegalView extends React.Component { interface ILegalView {
static propTypes = { server: string;
server: PropTypes.string, theme: string;
theme: PropTypes.string }
class LegalView extends React.Component<ILegalView, any> {
static navigationOptions: StackNavigationOptions = {
title: I18n.t('Legal')
}; };
onPressItem = ({ route }) => { onPressItem = ({ route }: { route: string }) => {
const { server, theme } = this.props; const { server, theme } = this.props;
if (!server) { if (!server) {
return; return;
@ -51,12 +55,8 @@ class LegalView extends React.Component {
} }
} }
const mapStateToProps = state => ({ const mapStateToProps = (state: any) => ({
server: state.server.server server: state.server.server
}); });
LegalView.navigationOptions = {
title: I18n.t('Legal')
};
export default connect(mapStateToProps)(withTheme(LegalView)); export default connect(mapStateToProps)(withTheme(LegalView));

View File

@ -3,8 +3,9 @@ import PropTypes from 'prop-types';
import { FlatList, StyleSheet, Text, View } from 'react-native'; import { FlatList, StyleSheet, Text, View } from 'react-native';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Q } from '@nozbe/watermelondb'; import { Q } from '@nozbe/watermelondb';
import { dequal } from 'dequal';
import * as List from '../containers/List'; import * as List from '../containers/List';
import Touch from '../utils/touch'; import Touch from '../utils/touch';
import database from '../lib/database'; import database from '../lib/database';
import RocketChat from '../lib/rocketchat'; import RocketChat from '../lib/rocketchat';
@ -57,13 +58,19 @@ class NewMessageView extends React.Component {
baseUrl: PropTypes.string, baseUrl: PropTypes.string,
user: PropTypes.shape({ user: PropTypes.shape({
id: PropTypes.string, id: PropTypes.string,
token: PropTypes.string token: PropTypes.string,
roles: PropTypes.array
}), }),
create: PropTypes.func, create: PropTypes.func,
maxUsers: PropTypes.number, maxUsers: PropTypes.number,
theme: PropTypes.string, theme: PropTypes.string,
isMasterDetail: PropTypes.bool, isMasterDetail: PropTypes.bool,
serverVersion: PropTypes.string serverVersion: PropTypes.string,
createTeamPermission: PropTypes.array,
createDirectMessagePermission: PropTypes.array,
createPublicChannelPermission: PropTypes.array,
createPrivateChannelPermission: PropTypes.array,
createDiscussionPermission: PropTypes.array
}; };
constructor(props) { constructor(props) {
@ -71,7 +78,8 @@ class NewMessageView extends React.Component {
this.init(); this.init();
this.state = { this.state = {
search: [], search: [],
chats: [] chats: [],
permissions: []
}; };
} }
@ -90,6 +98,30 @@ class NewMessageView extends React.Component {
} }
}; };
componentDidMount() {
this.handleHasPermission();
}
componentDidUpdate(prevProps) {
const {
createTeamPermission,
createPublicChannelPermission,
createPrivateChannelPermission,
createDirectMessagePermission,
createDiscussionPermission
} = this.props;
if (
!dequal(createTeamPermission, prevProps.createTeamPermission) ||
!dequal(createPublicChannelPermission, prevProps.createPublicChannelPermission) ||
!dequal(createPrivateChannelPermission, prevProps.createPrivateChannelPermission) ||
!dequal(createDirectMessagePermission, prevProps.createDirectMessagePermission) ||
!dequal(createDiscussionPermission, prevProps.createDiscussionPermission)
) {
this.handleHasPermission();
}
}
onSearchChangeText(text) { onSearchChangeText(text) {
this.search(text); this.search(text);
} }
@ -161,20 +193,43 @@ class NewMessageView extends React.Component {
Navigation.navigate('CreateDiscussionView'); Navigation.navigate('CreateDiscussionView');
}; };
handleHasPermission = async () => {
const {
createTeamPermission,
createDirectMessagePermission,
createPublicChannelPermission,
createPrivateChannelPermission,
createDiscussionPermission
} = this.props;
const permissions = [
createPublicChannelPermission,
createPrivateChannelPermission,
createTeamPermission,
createDirectMessagePermission,
createDiscussionPermission
];
const permissionsToCreate = await RocketChat.hasPermission(permissions);
this.setState({ permissions: permissionsToCreate });
};
renderHeader = () => { renderHeader = () => {
const { maxUsers, theme, serverVersion } = this.props; const { maxUsers, theme, serverVersion } = this.props;
const { permissions } = this.state;
return ( return (
<View style={{ backgroundColor: themes[theme].auxiliaryBackground }}> <View style={{ backgroundColor: themes[theme].auxiliaryBackground }}>
<SearchBox onChangeText={text => this.onSearchChangeText(text)} testID='new-message-view-search' /> <SearchBox onChangeText={text => this.onSearchChangeText(text)} testID='new-message-view-search' />
<View style={styles.buttonContainer}> <View style={styles.buttonContainer}>
{this.renderButton({ {permissions[0] || permissions[1]
onPress: this.createChannel, ? this.renderButton({
title: I18n.t('Create_Channel'), onPress: this.createChannel,
icon: 'channel-public', title: I18n.t('Create_Channel'),
testID: 'new-message-view-create-channel', icon: 'channel-public',
first: true testID: 'new-message-view-create-channel',
})} first: true
{compareServerVersion(serverVersion, '3.13.0', methods.greaterThanOrEqualTo) })
: null}
{compareServerVersion(serverVersion, '3.13.0', methods.greaterThanOrEqualTo) && permissions[2]
? this.renderButton({ ? this.renderButton({
onPress: this.createTeam, onPress: this.createTeam,
title: I18n.t('Create_Team'), title: I18n.t('Create_Team'),
@ -182,7 +237,7 @@ class NewMessageView extends React.Component {
testID: 'new-message-view-create-team' testID: 'new-message-view-create-team'
}) })
: null} : null}
{maxUsers > 2 {maxUsers > 2 && permissions[3]
? this.renderButton({ ? this.renderButton({
onPress: this.createGroupChat, onPress: this.createGroupChat,
title: I18n.t('Create_Direct_Messages'), title: I18n.t('Create_Direct_Messages'),
@ -190,12 +245,14 @@ class NewMessageView extends React.Component {
testID: 'new-message-view-create-direct-message' testID: 'new-message-view-create-direct-message'
}) })
: null} : null}
{this.renderButton({ {permissions[4]
onPress: this.createDiscussion, ? this.renderButton({
title: I18n.t('Create_Discussion'), onPress: this.createDiscussion,
icon: 'discussions', title: I18n.t('Create_Discussion'),
testID: 'new-message-view-create-discussion' icon: 'discussions',
})} testID: 'new-message-view-create-discussion'
})
: null}
</View> </View>
</View> </View>
); );
@ -261,7 +318,12 @@ const mapStateToProps = state => ({
isMasterDetail: state.app.isMasterDetail, isMasterDetail: state.app.isMasterDetail,
baseUrl: state.server.server, baseUrl: state.server.server,
maxUsers: state.settings.DirectMesssage_maxUsers || 1, maxUsers: state.settings.DirectMesssage_maxUsers || 1,
user: getUserSelector(state) user: getUserSelector(state),
createTeamPermission: state.permissions['create-team'],
createDirectMessagePermission: state.permissions['create-d'],
createPublicChannelPermission: state.permissions['create-c'],
createPrivateChannelPermission: state.permissions['create-p'],
createDiscussionPermission: state.permissions['start-discussion']
}); });
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({

View File

@ -446,7 +446,8 @@ class RoomMembersView extends React.Component {
type: allUsers ? 'all' : 'online', type: allUsers ? 'all' : 'online',
filter: filtering, filter: filtering,
skip: members.length, skip: members.length,
limit: PAGE_SIZE limit: PAGE_SIZE,
allUsers
}); });
this.setState({ this.setState({
members: members.concat(membersResult || []), members: members.concat(membersResult || []),

View File

@ -20,7 +20,8 @@ class RightButtonsContainer extends Component {
navigation: PropTypes.object, navigation: PropTypes.object,
isMasterDetail: PropTypes.bool, isMasterDetail: PropTypes.bool,
toggleFollowThread: PropTypes.func, toggleFollowThread: PropTypes.func,
joined: PropTypes.bool joined: PropTypes.bool,
encrypted: PropTypes.bool
}; };
constructor(props) { constructor(props) {
@ -137,11 +138,14 @@ class RightButtonsContainer extends Component {
goSearchView = () => { goSearchView = () => {
logEvent(events.ROOM_GO_SEARCH); logEvent(events.ROOM_GO_SEARCH);
const { rid, t, navigation, isMasterDetail } = this.props; const { rid, t, navigation, isMasterDetail, encrypted } = this.props;
if (isMasterDetail) { if (isMasterDetail) {
navigation.navigate('ModalStackNavigator', { screen: 'SearchMessagesView', params: { rid, showCloseModal: true } }); navigation.navigate('ModalStackNavigator', {
screen: 'SearchMessagesView',
params: { rid, showCloseModal: true, encrypted }
});
} else { } else {
navigation.navigate('SearchMessagesView', { rid, t }); navigation.navigate('SearchMessagesView', { rid, t, encrypted });
} }
}; };

View File

@ -362,6 +362,7 @@ class RoomView extends React.Component {
const t = room?.t; const t = room?.t;
const teamMain = room?.teamMain; const teamMain = room?.teamMain;
const teamId = room?.teamId; const teamId = room?.teamId;
const encrypted = room?.encrypted;
const { id: userId, token } = user; const { id: userId, token } = user;
const avatar = room?.name; const avatar = room?.name;
const visitor = room?.visitor; const visitor = room?.visitor;
@ -424,6 +425,7 @@ class RoomView extends React.Component {
teamMain={teamMain} teamMain={teamMain}
joined={joined} joined={joined}
t={t} t={t}
encrypted={encrypted}
navigation={navigation} navigation={navigation}
toggleFollowThread={this.toggleFollowThread} toggleFollowThread={this.toggleFollowThread}
/> />

View File

@ -2,12 +2,7 @@ import React, { PureComponent } from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { import { toggleServerDropdown, closeServerDropdown, setSearch as setSearchAction } from '../../../actions/rooms';
closeServerDropdown,
closeSortDropdown,
setSearch as setSearchAction,
toggleServerDropdown
} from '../../../actions/rooms';
import { withTheme } from '../../../theme'; import { withTheme } from '../../../theme';
import EventEmitter from '../../../utils/events'; import EventEmitter from '../../../utils/events';
import { KEY_COMMAND, handleCommandOpenServerDropdown } from '../../../commands'; import { KEY_COMMAND, handleCommandOpenServerDropdown } from '../../../commands';
@ -18,7 +13,6 @@ import Header from './Header';
class RoomsListHeaderView extends PureComponent { class RoomsListHeaderView extends PureComponent {
static propTypes = { static propTypes = {
showServerDropdown: PropTypes.bool, showServerDropdown: PropTypes.bool,
showSortDropdown: PropTypes.bool,
showSearchHeader: PropTypes.bool, showSearchHeader: PropTypes.bool,
serverName: PropTypes.string, serverName: PropTypes.string,
connecting: PropTypes.bool, connecting: PropTypes.bool,
@ -28,7 +22,6 @@ class RoomsListHeaderView extends PureComponent {
server: PropTypes.string, server: PropTypes.string,
open: PropTypes.func, open: PropTypes.func,
close: PropTypes.func, close: PropTypes.func,
closeSort: PropTypes.func,
setSearch: PropTypes.func setSearch: PropTypes.func
}; };
@ -58,14 +51,9 @@ class RoomsListHeaderView extends PureComponent {
onPress = () => { onPress = () => {
logEvent(events.RL_TOGGLE_SERVER_DROPDOWN); logEvent(events.RL_TOGGLE_SERVER_DROPDOWN);
const { showServerDropdown, showSortDropdown, close, open, closeSort } = this.props; const { showServerDropdown, close, open } = this.props;
if (showServerDropdown) { if (showServerDropdown) {
close(); close();
} else if (showSortDropdown) {
closeSort();
setTimeout(() => {
open();
}, 300);
} else { } else {
open(); open();
} }
@ -93,7 +81,6 @@ class RoomsListHeaderView extends PureComponent {
const mapStateToProps = state => ({ const mapStateToProps = state => ({
showServerDropdown: state.rooms.showServerDropdown, showServerDropdown: state.rooms.showServerDropdown,
showSortDropdown: state.rooms.showSortDropdown,
showSearchHeader: state.rooms.showSearchHeader, showSearchHeader: state.rooms.showSearchHeader,
connecting: state.meteor.connecting || state.server.loading, connecting: state.meteor.connecting || state.server.loading,
connected: state.meteor.connected, connected: state.meteor.connected,
@ -105,7 +92,6 @@ const mapStateToProps = state => ({
const mapDispatchtoProps = dispatch => ({ const mapDispatchtoProps = dispatch => ({
close: () => dispatch(closeServerDropdown()), close: () => dispatch(closeServerDropdown()),
open: () => dispatch(toggleServerDropdown()), open: () => dispatch(toggleServerDropdown()),
closeSort: () => dispatch(closeSortDropdown()),
setSearch: searchText => dispatch(setSearchAction(searchText)) setSearch: searchText => dispatch(setSearchAction(searchText))
}); });

View File

@ -2,16 +2,13 @@ import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { withTheme } from '../../../theme'; import { withTheme } from '../../../theme';
import I18n from '../../../i18n';
import * as List from '../../../containers/List'; import * as List from '../../../containers/List';
import { E2E_BANNER_TYPE } from '../../../lib/encryption/constants'; import { E2E_BANNER_TYPE } from '../../../lib/encryption/constants';
import { themes } from '../../../constants/colors'; import { themes } from '../../../constants/colors';
import OmnichannelStatus from '../../../ee/omnichannel/containers/OmnichannelStatus'; import OmnichannelStatus from '../../../ee/omnichannel/containers/OmnichannelStatus';
const ListHeader = React.memo( const ListHeader = React.memo(
({ searching, sortBy, toggleSort, goEncryption, goQueue, queueSize, inquiryEnabled, encryptionBanner, user, theme }) => { ({ searching, goEncryption, goQueue, queueSize, inquiryEnabled, encryptionBanner, user, theme }) => {
const sortTitle = I18n.t('Sorting_by', { key: I18n.t(sortBy === 'alphabetical' ? 'name' : 'activity') });
if (searching) { if (searching) {
return null; return null;
} }
@ -36,13 +33,6 @@ const ListHeader = React.memo(
<List.Separator /> <List.Separator />
</> </>
) : null} ) : null}
<List.Item
title={sortTitle}
left={() => <List.Icon name='sort' />}
color={themes[theme].auxiliaryText}
onPress={toggleSort}
translateTitle={false}
/>
<List.Separator /> <List.Separator />
<OmnichannelStatus <OmnichannelStatus
searching={searching} searching={searching}
@ -58,8 +48,6 @@ const ListHeader = React.memo(
ListHeader.propTypes = { ListHeader.propTypes = {
searching: PropTypes.bool, searching: PropTypes.bool,
sortBy: PropTypes.string,
toggleSort: PropTypes.func,
goEncryption: PropTypes.func, goEncryption: PropTypes.func,
goQueue: PropTypes.func, goQueue: PropTypes.func,
queueSize: PropTypes.number, queueSize: PropTypes.number,

View File

@ -1,207 +0,0 @@
import React, { PureComponent } from 'react';
import { Animated, Easing, TouchableWithoutFeedback } from 'react-native';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { withSafeAreaInsets } from 'react-native-safe-area-context';
import styles from '../styles';
import * as List from '../../../containers/List';
import RocketChat from '../../../lib/rocketchat';
import { setPreference } from '../../../actions/sortPreferences';
import log, { events, logEvent } from '../../../utils/log';
import I18n from '../../../i18n';
import { withTheme } from '../../../theme';
import { themes } from '../../../constants/colors';
import { headerHeight } from '../../../containers/Header';
const ANIMATION_DURATION = 200;
class Sort extends PureComponent {
static propTypes = {
closeSortDropdown: PropTypes.bool,
close: PropTypes.func,
sortBy: PropTypes.string,
groupByType: PropTypes.bool,
showFavorites: PropTypes.bool,
showUnread: PropTypes.bool,
isMasterDetail: PropTypes.bool,
theme: PropTypes.string,
insets: PropTypes.object,
setSortPreference: PropTypes.func
};
constructor(props) {
super(props);
this.animatedValue = new Animated.Value(0);
}
componentDidMount() {
Animated.timing(this.animatedValue, {
toValue: 1,
duration: ANIMATION_DURATION,
easing: Easing.inOut(Easing.quad),
useNativeDriver: true
}).start();
}
componentDidUpdate(prevProps) {
const { closeSortDropdown } = this.props;
if (prevProps.closeSortDropdown !== closeSortDropdown) {
this.close();
}
}
setSortPreference = param => {
const { setSortPreference } = this.props;
try {
setSortPreference(param);
RocketChat.saveSortPreference(param);
} catch (e) {
logEvent(events.RL_SORT_CHANNELS_F);
log(e);
}
};
sortByName = () => {
logEvent(events.RL_SORT_CHANNELS_BY_NAME);
this.setSortPreference({ sortBy: 'alphabetical' });
this.close();
};
sortByActivity = () => {
logEvent(events.RL_SORT_CHANNELS_BY_ACTIVITY);
this.setSortPreference({ sortBy: 'activity' });
this.close();
};
toggleGroupByType = () => {
logEvent(events.RL_GROUP_CHANNELS_BY_TYPE);
const { groupByType } = this.props;
this.setSortPreference({ groupByType: !groupByType });
};
toggleGroupByFavorites = () => {
logEvent(events.RL_GROUP_CHANNELS_BY_FAVORITE);
const { showFavorites } = this.props;
this.setSortPreference({ showFavorites: !showFavorites });
};
toggleUnread = () => {
logEvent(events.RL_GROUP_CHANNELS_BY_UNREAD);
const { showUnread } = this.props;
this.setSortPreference({ showUnread: !showUnread });
};
close = () => {
const { close } = this.props;
Animated.timing(this.animatedValue, {
toValue: 0,
duration: ANIMATION_DURATION,
easing: Easing.inOut(Easing.quad),
useNativeDriver: true
}).start(() => close());
};
renderCheck = () => {
const { theme } = this.props;
return <List.Icon name='check' color={themes[theme].tintColor} />;
};
render() {
const { isMasterDetail, insets } = this.props;
const statusBarHeight = insets?.top ?? 0;
const heightDestination = isMasterDetail ? headerHeight + statusBarHeight : 0;
const translateY = this.animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [-326, heightDestination]
});
const { sortBy, groupByType, showFavorites, showUnread, theme } = this.props;
const backdropOpacity = this.animatedValue.interpolate({
inputRange: [0, 1],
outputRange: [0, themes[theme].backdropOpacity]
});
return (
<>
<TouchableWithoutFeedback onPress={this.close}>
<Animated.View
style={[
styles.backdrop,
{
backgroundColor: themes[theme].backdropColor,
opacity: backdropOpacity,
top: heightDestination
}
]}
/>
</TouchableWithoutFeedback>
<Animated.View
style={[
styles.dropdownContainer,
{
transform: [{ translateY }],
backgroundColor: themes[theme].backgroundColor,
borderColor: themes[theme].separatorColor
}
]}>
<List.Item
title={I18n.t('Sorting_by', { key: I18n.t(sortBy === 'alphabetical' ? 'name' : 'activity') })}
left={() => <List.Icon name='sort' />}
color={themes[theme].auxiliaryText}
onPress={this.close}
translateTitle={false}
/>
<List.Separator />
<List.Item
title='Alphabetical'
left={() => <List.Icon name='sort-az' />}
color={themes[theme].auxiliaryText}
onPress={this.sortByName}
right={() => (sortBy === 'alphabetical' ? this.renderCheck() : null)}
/>
<List.Item
title='Activity'
left={() => <List.Icon name='clock' />}
color={themes[theme].auxiliaryText}
onPress={this.sortByActivity}
right={() => (sortBy === 'activity' ? this.renderCheck() : null)}
/>
<List.Separator />
<List.Item
title='Group_by_type'
left={() => <List.Icon name='group-by-type' />}
color={themes[theme].auxiliaryText}
onPress={this.toggleGroupByType}
right={() => (groupByType ? this.renderCheck() : null)}
/>
<List.Item
title='Group_by_favorites'
left={() => <List.Icon name='star' />}
color={themes[theme].auxiliaryText}
onPress={this.toggleGroupByFavorites}
right={() => (showFavorites ? this.renderCheck() : null)}
/>
<List.Item
title='Unread_on_top'
left={() => <List.Icon name='unread-on-top-disabled' />}
color={themes[theme].auxiliaryText}
onPress={this.toggleUnread}
right={() => (showUnread ? this.renderCheck() : null)}
/>
</Animated.View>
</>
);
}
}
const mapStateToProps = state => ({
closeSortDropdown: state.rooms.closeSortDropdown,
isMasterDetail: state.app.isMasterDetail
});
const mapDispatchToProps = dispatch => ({
setSortPreference: preference => dispatch(setPreference(preference))
});
export default connect(mapStateToProps, mapDispatchToProps)(withSafeAreaInsets(withTheme(Sort)));

View File

@ -9,15 +9,14 @@ import { withSafeAreaInsets } from 'react-native-safe-area-context';
import database from '../../lib/database'; import database from '../../lib/database';
import RocketChat from '../../lib/rocketchat'; import RocketChat from '../../lib/rocketchat';
import RoomItem, { ROW_HEIGHT } from '../../presentation/RoomItem'; import RoomItem, { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from '../../presentation/RoomItem';
import log, { events, logEvent } from '../../utils/log'; import log, { logEvent, events } from '../../utils/log';
import I18n from '../../i18n'; import I18n from '../../i18n';
import { import {
closeSearchHeader as closeSearchHeaderAction, closeSearchHeader as closeSearchHeaderAction,
closeServerDropdown as closeServerDropdownAction, closeServerDropdown as closeServerDropdownAction,
openSearchHeader as openSearchHeaderAction, openSearchHeader as openSearchHeaderAction,
roomsRequest as roomsRequestAction, roomsRequest as roomsRequestAction
toggleSortDropdown as toggleSortDropdownAction
} from '../../actions/rooms'; } from '../../actions/rooms';
import { appStart as appStartAction, ROOT_OUTSIDE } from '../../actions/app'; import { appStart as appStartAction, ROOT_OUTSIDE } from '../../actions/app';
import debounce from '../../utils/debounce'; import debounce from '../../utils/debounce';
@ -50,11 +49,11 @@ import { showConfirmationAlert, showErrorAlert } from '../../utils/info';
import { E2E_BANNER_TYPE } from '../../lib/encryption/constants'; import { E2E_BANNER_TYPE } from '../../lib/encryption/constants';
import { getInquiryQueueSelector } from '../../ee/omnichannel/selectors/inquiry'; import { getInquiryQueueSelector } from '../../ee/omnichannel/selectors/inquiry';
import { changeLivechatStatus, isOmnichannelStatusAvailable } from '../../ee/omnichannel/lib'; import { changeLivechatStatus, isOmnichannelStatusAvailable } from '../../ee/omnichannel/lib';
import { DISPLAY_MODE_CONDENSED } from '../../constants/constantDisplayMode';
import styles from './styles';
import ServerDropdown from './ServerDropdown';
import ListHeader from './ListHeader'; import ListHeader from './ListHeader';
import RoomsListHeaderView from './Header'; import RoomsListHeaderView from './Header';
import ServerDropdown from './ServerDropdown';
import SortDropdown from './SortDropdown';
import styles from './styles';
const INITIAL_NUM_TO_RENDER = isTablet ? 20 : 12; const INITIAL_NUM_TO_RENDER = isTablet ? 20 : 12;
const CHATS_HEADER = 'Chats'; const CHATS_HEADER = 'Chats';
@ -77,11 +76,6 @@ const shouldUpdateProps = [
'searchText', 'searchText',
'loadingServer', 'loadingServer',
'showServerDropdown', 'showServerDropdown',
'showSortDropdown',
'sortBy',
'groupByType',
'showFavorites',
'showUnread',
'useRealName', 'useRealName',
'StoreLastMessage', 'StoreLastMessage',
'theme', 'theme',
@ -89,11 +83,21 @@ const shouldUpdateProps = [
'refreshing', 'refreshing',
'queueSize', 'queueSize',
'inquiryEnabled', 'inquiryEnabled',
'encryptionBanner' 'encryptionBanner',
'createTeamPermission',
'createDirectMessagePermission',
'createPublicChannelPermission',
'createPrivateChannelPermission',
'createDiscussionPermission'
]; ];
const getItemLayout = (data, index) => ({
length: ROW_HEIGHT, const sortPreferencesShouldUpdate = ['sortBy', 'groupByType', 'showFavorites', 'showUnread'];
offset: ROW_HEIGHT * index,
const displayPropsShouldUpdate = ['showAvatar', 'displayMode'];
const getItemLayout = (data, index, height) => ({
length: height,
offset: height * index,
index index
}); });
const keyExtractor = item => item.rid; const keyExtractor = item => item.rid;
@ -106,14 +110,13 @@ class RoomsListView extends React.Component {
username: PropTypes.string, username: PropTypes.string,
token: PropTypes.string, token: PropTypes.string,
statusLivechat: PropTypes.string, statusLivechat: PropTypes.string,
roles: PropTypes.object roles: PropTypes.array
}), }),
server: PropTypes.string, server: PropTypes.string,
searchText: PropTypes.string, searchText: PropTypes.string,
changingServer: PropTypes.bool, changingServer: PropTypes.bool,
loadingServer: PropTypes.bool, loadingServer: PropTypes.bool,
showServerDropdown: PropTypes.bool, showServerDropdown: PropTypes.bool,
showSortDropdown: PropTypes.bool,
sortBy: PropTypes.string, sortBy: PropTypes.string,
groupByType: PropTypes.bool, groupByType: PropTypes.bool,
showFavorites: PropTypes.bool, showFavorites: PropTypes.bool,
@ -121,7 +124,6 @@ class RoomsListView extends React.Component {
refreshing: PropTypes.bool, refreshing: PropTypes.bool,
StoreLastMessage: PropTypes.bool, StoreLastMessage: PropTypes.bool,
theme: PropTypes.string, theme: PropTypes.string,
toggleSortDropdown: PropTypes.func,
openSearchHeader: PropTypes.func, openSearchHeader: PropTypes.func,
closeSearchHeader: PropTypes.func, closeSearchHeader: PropTypes.func,
appStart: PropTypes.func, appStart: PropTypes.func,
@ -135,6 +137,13 @@ class RoomsListView extends React.Component {
queueSize: PropTypes.number, queueSize: PropTypes.number,
inquiryEnabled: PropTypes.bool, inquiryEnabled: PropTypes.bool,
encryptionBanner: PropTypes.string, encryptionBanner: PropTypes.string,
showAvatar: PropTypes.bool,
displayMode: PropTypes.string,
createTeamPermission: PropTypes.array,
createDirectMessagePermission: PropTypes.array,
createPublicChannelPermission: PropTypes.array,
createPrivateChannelPermission: PropTypes.array,
createDiscussionPermission: PropTypes.array,
initAdd: PropTypes.func initAdd: PropTypes.func
}; };
@ -152,7 +161,8 @@ class RoomsListView extends React.Component {
loading: true, loading: true,
chatsUpdate: [], chatsUpdate: [],
chats: [], chats: [],
item: {} item: {},
canCreateRoom: false
}; };
this.setHeader(); this.setHeader();
this.getSubscriptions(); this.getSubscriptions();
@ -160,6 +170,7 @@ class RoomsListView extends React.Component {
componentDidMount() { componentDidMount() {
const { navigation, closeServerDropdown } = this.props; const { navigation, closeServerDropdown } = this.props;
this.handleHasPermission();
this.mounted = true; this.mounted = true;
if (isTablet) { if (isTablet) {
@ -168,6 +179,11 @@ class RoomsListView extends React.Component {
this.unsubscribeFocus = navigation.addListener('focus', () => { this.unsubscribeFocus = navigation.addListener('focus', () => {
Orientation.unlockAllOrientations(); Orientation.unlockAllOrientations();
this.animated = true; this.animated = true;
// Check if there were changes with sort preference, then call getSubscription to remount the list
if (this.sortPreferencesChanged) {
this.getSubscriptions();
this.sortPreferencesChanged = false;
}
// Check if there were changes while not focused (it's set on sCU) // Check if there were changes while not focused (it's set on sCU)
if (this.shouldUpdate) { if (this.shouldUpdate) {
this.forceUpdate(); this.forceUpdate();
@ -203,13 +219,27 @@ class RoomsListView extends React.Component {
} }
shouldComponentUpdate(nextProps, nextState) { shouldComponentUpdate(nextProps, nextState) {
const { chatsUpdate, searching, item } = this.state; const { chatsUpdate, searching, item, canCreateRoom } = this.state;
// eslint-disable-next-line react/destructuring-assignment // eslint-disable-next-line react/destructuring-assignment
const propsUpdated = shouldUpdateProps.some(key => nextProps[key] !== this.props[key]); const propsUpdated = shouldUpdateProps.some(key => nextProps[key] !== this.props[key]);
if (propsUpdated) { if (propsUpdated) {
return true; return true;
} }
// check if some display props are changed to force update when focus this view again
// eslint-disable-next-line react/destructuring-assignment
const displayUpdated = displayPropsShouldUpdate.some(key => nextProps[key] !== this.props[key]);
if (displayUpdated) {
this.shouldUpdate = true;
}
// check if some sort preferences are changed to getSubscription() when focus this view again
// eslint-disable-next-line react/destructuring-assignment
const sortPreferencesUpdate = sortPreferencesShouldUpdate.some(key => nextProps[key] !== this.props[key]);
if (sortPreferencesUpdate) {
this.sortPreferencesChanged = true;
}
// Compare changes only once // Compare changes only once
const chatsNotEqual = !dequal(nextState.chatsUpdate, chatsUpdate); const chatsNotEqual = !dequal(nextState.chatsUpdate, chatsUpdate);
@ -222,6 +252,10 @@ class RoomsListView extends React.Component {
return true; return true;
} }
if (nextState.canCreateRoom !== canCreateRoom) {
return true;
}
if (nextState.item?.rid !== item?.rid) { if (nextState.item?.rid !== item?.rid) {
return true; return true;
} }
@ -257,7 +291,22 @@ class RoomsListView extends React.Component {
} }
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
const { sortBy, groupByType, showFavorites, showUnread, rooms, isMasterDetail, insets } = this.props; const {
sortBy,
groupByType,
showFavorites,
showUnread,
rooms,
isMasterDetail,
insets,
createTeamPermission,
createPublicChannelPermission,
createPrivateChannelPermission,
createDirectMessagePermission,
createDiscussionPermission,
showAvatar,
displayMode
} = this.props;
const { item } = this.state; const { item } = this.state;
if ( if (
@ -265,7 +314,9 @@ class RoomsListView extends React.Component {
prevProps.sortBy === sortBy && prevProps.sortBy === sortBy &&
prevProps.groupByType === groupByType && prevProps.groupByType === groupByType &&
prevProps.showFavorites === showFavorites && prevProps.showFavorites === showFavorites &&
prevProps.showUnread === showUnread prevProps.showUnread === showUnread &&
prevProps.showAvatar === showAvatar &&
prevProps.displayMode === displayMode
) )
) { ) {
this.getSubscriptions(); this.getSubscriptions();
@ -278,6 +329,17 @@ class RoomsListView extends React.Component {
if (insets.left !== prevProps.insets.left || insets.right !== prevProps.insets.right) { if (insets.left !== prevProps.insets.left || insets.right !== prevProps.insets.right) {
this.setHeader(); this.setHeader();
} }
if (
!dequal(createTeamPermission, prevProps.createTeamPermission) ||
!dequal(createPublicChannelPermission, prevProps.createPublicChannelPermission) ||
!dequal(createPrivateChannelPermission, prevProps.createPrivateChannelPermission) ||
!dequal(createDirectMessagePermission, prevProps.createDirectMessagePermission) ||
!dequal(createDiscussionPermission, prevProps.createDiscussionPermission)
) {
this.handleHasPermission();
this.setHeader();
}
} }
componentWillUnmount() { componentWillUnmount() {
@ -297,10 +359,31 @@ class RoomsListView extends React.Component {
console.countReset(`${this.constructor.name}.render calls`); console.countReset(`${this.constructor.name}.render calls`);
} }
handleHasPermission = async () => {
const {
createTeamPermission,
createDirectMessagePermission,
createPublicChannelPermission,
createPrivateChannelPermission,
createDiscussionPermission
} = this.props;
const permissions = [
createPublicChannelPermission,
createPrivateChannelPermission,
createTeamPermission,
createDirectMessagePermission,
createDiscussionPermission
];
const permissionsToCreate = await RocketChat.hasPermission(permissions);
const canCreateRoom = permissionsToCreate.filter(r => r === true).length > 0;
this.setState({ canCreateRoom }, () => this.setHeader());
};
getHeader = () => { getHeader = () => {
const { searching } = this.state; const { searching, canCreateRoom } = this.state;
const { navigation, isMasterDetail, insets } = this.props; const { navigation, isMasterDetail, insets } = this.props;
const headerTitlePosition = getHeaderTitlePosition({ insets, numIconsRight: searching ? 0 : 3 }); const headerTitlePosition = getHeaderTitlePosition({ insets, numIconsRight: searching ? 0 : 3 });
return { return {
headerTitleAlign: 'left', headerTitleAlign: 'left',
headerLeft: () => headerLeft: () =>
@ -327,7 +410,9 @@ class RoomsListView extends React.Component {
headerRight: () => headerRight: () =>
searching ? null : ( searching ? null : (
<HeaderButton.Container> <HeaderButton.Container>
<HeaderButton.Item iconName='create' onPress={this.goToNewMessage} testID='rooms-list-view-create-channel' /> {canCreateRoom ? (
<HeaderButton.Item iconName='create' onPress={this.goToNewMessage} testID='rooms-list-view-create-channel' />
) : null}
<HeaderButton.Item iconName='search' onPress={this.initSearching} testID='rooms-list-view-search' /> <HeaderButton.Item iconName='search' onPress={this.initSearching} testID='rooms-list-view-search' />
<HeaderButton.Item iconName='directory' onPress={this.goDirectory} testID='rooms-list-view-directory' /> <HeaderButton.Item iconName='directory' onPress={this.goDirectory} testID='rooms-list-view-directory' />
</HeaderButton.Container> </HeaderButton.Container>
@ -553,16 +638,6 @@ class RoomsListView extends React.Component {
} }
}; };
toggleSort = () => {
logEvent(events.RL_TOGGLE_SORT_DROPDOWN);
const { toggleSortDropdown } = this.props;
this.scrollToTop();
setTimeout(() => {
toggleSortDropdown();
}, 100);
};
toggleFav = async (rid, favorite) => { toggleFav = async (rid, favorite) => {
logEvent(favorite ? events.RL_UNFAVORITE_CHANNEL : events.RL_FAVORITE_CHANNEL); logEvent(favorite ? events.RL_UNFAVORITE_CHANNEL : events.RL_FAVORITE_CHANNEL);
try { try {
@ -811,12 +886,10 @@ class RoomsListView extends React.Component {
renderListHeader = () => { renderListHeader = () => {
const { searching } = this.state; const { searching } = this.state;
const { sortBy, queueSize, inquiryEnabled, encryptionBanner, user } = this.props; const { queueSize, inquiryEnabled, encryptionBanner, user } = this.props;
return ( return (
<ListHeader <ListHeader
searching={searching} searching={searching}
sortBy={sortBy}
toggleSort={this.toggleSort}
goEncryption={this.goEncryption} goEncryption={this.goEncryption}
goQueue={this.goQueue} goQueue={this.goQueue}
queueSize={queueSize} queueSize={queueSize}
@ -850,7 +923,9 @@ class RoomsListView extends React.Component {
useRealName, useRealName,
theme, theme,
isMasterDetail, isMasterDetail,
width width,
showAvatar,
displayMode
} = this.props; } = this.props;
const id = this.getUidDirectMessage(item); const id = this.getUidDirectMessage(item);
@ -875,6 +950,8 @@ class RoomsListView extends React.Component {
getIsRead={this.isRead} getIsRead={this.isRead}
visitor={item.visitor} visitor={item.visitor}
isFocused={currentItem?.rid === item.rid} isFocused={currentItem?.rid === item.rid}
showAvatar={showAvatar}
displayMode={displayMode}
/> />
); );
}; };
@ -890,7 +967,9 @@ class RoomsListView extends React.Component {
renderScroll = () => { renderScroll = () => {
const { loading, chats, search, searching } = this.state; const { loading, chats, search, searching } = this.state;
const { theme, refreshing } = this.props; const { theme, refreshing, displayMode } = this.props;
const height = displayMode === DISPLAY_MODE_CONDENSED ? ROW_HEIGHT_CONDENSED : ROW_HEIGHT;
if (loading) { if (loading) {
return <ActivityIndicator theme={theme} />; return <ActivityIndicator theme={theme} />;
@ -905,7 +984,7 @@ class RoomsListView extends React.Component {
style={[styles.list, { backgroundColor: themes[theme].backgroundColor }]} style={[styles.list, { backgroundColor: themes[theme].backgroundColor }]}
renderItem={this.renderItem} renderItem={this.renderItem}
ListHeaderComponent={this.renderListHeader} ListHeaderComponent={this.renderListHeader}
getItemLayout={getItemLayout} getItemLayout={(data, index) => getItemLayout(data, index, height)}
removeClippedSubviews={isIOS} removeClippedSubviews={isIOS}
keyboardShouldPersistTaps='always' keyboardShouldPersistTaps='always'
initialNumToRender={INITIAL_NUM_TO_RENDER} initialNumToRender={INITIAL_NUM_TO_RENDER}
@ -921,23 +1000,13 @@ class RoomsListView extends React.Component {
render = () => { render = () => {
console.count(`${this.constructor.name}.render calls`); console.count(`${this.constructor.name}.render calls`);
const { sortBy, groupByType, showFavorites, showUnread, showServerDropdown, showSortDropdown, theme, navigation } = const { showServerDropdown, theme, navigation } = this.props;
this.props;
return ( return (
<SafeAreaView testID='rooms-list-view' style={{ backgroundColor: themes[theme].backgroundColor }}> <SafeAreaView testID='rooms-list-view' style={{ backgroundColor: themes[theme].backgroundColor }}>
<StatusBar /> <StatusBar />
{this.renderHeader()} {this.renderHeader()}
{this.renderScroll()} {this.renderScroll()}
{showSortDropdown ? (
<SortDropdown
close={this.toggleSort}
sortBy={sortBy}
groupByType={groupByType}
showFavorites={showFavorites}
showUnread={showUnread}
/>
) : null}
{showServerDropdown ? <ServerDropdown navigation={navigation} /> : null} {showServerDropdown ? <ServerDropdown navigation={navigation} /> : null}
</SafeAreaView> </SafeAreaView>
); );
@ -952,7 +1021,6 @@ const mapStateToProps = state => ({
searchText: state.rooms.searchText, searchText: state.rooms.searchText,
loadingServer: state.server.loading, loadingServer: state.server.loading,
showServerDropdown: state.rooms.showServerDropdown, showServerDropdown: state.rooms.showServerDropdown,
showSortDropdown: state.rooms.showSortDropdown,
refreshing: state.rooms.refreshing, refreshing: state.rooms.refreshing,
sortBy: state.sortPreferences.sortBy, sortBy: state.sortPreferences.sortBy,
groupByType: state.sortPreferences.groupByType, groupByType: state.sortPreferences.groupByType,
@ -963,11 +1031,17 @@ const mapStateToProps = state => ({
rooms: state.room.rooms, rooms: state.room.rooms,
queueSize: getInquiryQueueSelector(state).length, queueSize: getInquiryQueueSelector(state).length,
inquiryEnabled: state.inquiry.enabled, inquiryEnabled: state.inquiry.enabled,
encryptionBanner: state.encryption.banner encryptionBanner: state.encryption.banner,
showAvatar: state.sortPreferences.showAvatar,
displayMode: state.sortPreferences.displayMode,
createTeamPermission: state.permissions['create-team'],
createDirectMessagePermission: state.permissions['create-d'],
createPublicChannelPermission: state.permissions['create-c'],
createPrivateChannelPermission: state.permissions['create-p'],
createDiscussionPermission: state.permissions['start-discussion']
}); });
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({
toggleSortDropdown: () => dispatch(toggleSortDropdownAction()),
openSearchHeader: () => dispatch(openSearchHeaderAction()), openSearchHeader: () => dispatch(openSearchHeaderAction()),
closeSearchHeader: () => dispatch(closeSearchHeaderAction()), closeSearchHeader: () => dispatch(closeSearchHeaderAction()),
roomsRequest: params => dispatch(roomsRequestAction(params)), roomsRequest: params => dispatch(roomsRequestAction(params)),

View File

@ -24,8 +24,11 @@ import database from '../../lib/database';
import { sanitizeLikeString } from '../../lib/database/utils'; import { sanitizeLikeString } from '../../lib/database/utils';
import getThreadName from '../../lib/methods/getThreadName'; import getThreadName from '../../lib/methods/getThreadName';
import getRoomInfo from '../../lib/methods/getRoomInfo'; import getRoomInfo from '../../lib/methods/getRoomInfo';
import { isIOS } from '../../utils/deviceInfo';
import { compareServerVersion, methods } from '../../lib/utils';
import styles from './styles'; import styles from './styles';
const QUERY_SIZE = 50;
class SearchMessagesView extends React.Component { class SearchMessagesView extends React.Component {
static navigationOptions = ({ navigation, route }) => { static navigationOptions = ({ navigation, route }) => {
const options = { const options = {
@ -43,6 +46,7 @@ class SearchMessagesView extends React.Component {
route: PropTypes.object, route: PropTypes.object,
user: PropTypes.object, user: PropTypes.object,
baseUrl: PropTypes.string, baseUrl: PropTypes.string,
serverVersion: PropTypes.string,
customEmojis: PropTypes.object, customEmojis: PropTypes.object,
theme: PropTypes.string, theme: PropTypes.string,
useRealName: PropTypes.bool useRealName: PropTypes.bool
@ -55,6 +59,7 @@ class SearchMessagesView extends React.Component {
messages: [], messages: [],
searchText: '' searchText: ''
}; };
this.offset = 0;
this.rid = props.route.params?.rid; this.rid = props.route.params?.rid;
this.t = props.route.params?.t; this.t = props.route.params?.t;
this.encrypted = props.route.params?.encrypted; this.encrypted = props.route.params?.encrypted;
@ -88,6 +93,9 @@ class SearchMessagesView extends React.Component {
// Handle encrypted rooms search messages // Handle encrypted rooms search messages
searchMessages = async searchText => { searchMessages = async searchText => {
if (!searchText) {
return [];
}
// If it's a encrypted, room we'll search only on the local stored messages // If it's a encrypted, room we'll search only on the local stored messages
if (this.encrypted) { if (this.encrypted) {
const db = database.active; const db = database.active;
@ -103,25 +111,33 @@ class SearchMessagesView extends React.Component {
.fetch(); .fetch();
} }
// If it's not a encrypted room, search messages on the server // If it's not a encrypted room, search messages on the server
const result = await RocketChat.searchMessages(this.rid, searchText); const result = await RocketChat.searchMessages(this.rid, searchText, QUERY_SIZE, this.offset);
if (result.success) { if (result.success) {
return result.messages; return result.messages;
} }
}; };
search = debounce(async searchText => { getMessages = async (searchText, debounced) => {
this.setState({ searchText, loading: true, messages: [] });
try { try {
const messages = await this.searchMessages(searchText); const messages = await this.searchMessages(searchText);
this.setState({ this.setState(prevState => ({
messages: messages || [], messages: debounced ? messages : [...prevState.messages, ...messages],
loading: false loading: false
}); }));
} catch (e) { } catch (e) {
this.setState({ loading: false }); this.setState({ loading: false });
log(e); log(e);
} }
};
search = searchText => {
this.offset = 0;
this.setState({ searchText, loading: true, messages: [] });
this.searchDebounced(searchText);
};
searchDebounced = debounce(async searchText => {
await this.getMessages(searchText, true);
}, 1000); }, 1000);
getCustomEmoji = name => { getCustomEmoji = name => {
@ -168,6 +184,23 @@ class SearchMessagesView extends React.Component {
} }
}; };
onEndReached = async () => {
const { serverVersion } = this.props;
const { searchText, messages, loading } = this.state;
if (
messages.length < this.offset ||
this.encrypted ||
loading ||
compareServerVersion(serverVersion, '3.17.0', methods.lowerThan)
) {
return;
}
this.setState({ loading: true });
this.offset += QUERY_SIZE;
await this.getMessages(searchText);
};
renderEmpty = () => { renderEmpty = () => {
const { theme } = this.props; const { theme } = this.props;
return ( return (
@ -212,8 +245,10 @@ class SearchMessagesView extends React.Component {
renderItem={this.renderItem} renderItem={this.renderItem}
style={[styles.list, { backgroundColor: themes[theme].backgroundColor }]} style={[styles.list, { backgroundColor: themes[theme].backgroundColor }]}
keyExtractor={item => item._id} keyExtractor={item => item._id}
onEndReached={this.load} onEndReached={this.onEndReached}
ListFooterComponent={loading ? <ActivityIndicator theme={theme} /> : null} ListFooterComponent={loading ? <ActivityIndicator theme={theme} /> : null}
onEndReachedThreshold={0.5}
removeClippedSubviews={isIOS}
{...scrollPersistTaps} {...scrollPersistTaps}
/> />
); );
@ -243,6 +278,7 @@ class SearchMessagesView extends React.Component {
} }
const mapStateToProps = state => ({ const mapStateToProps = state => ({
serverVersion: state.server.version,
baseUrl: state.server.server, baseUrl: state.server.server,
user: getUserSelector(state), user: getUserSelector(state),
useRealName: state.settings.UI_Use_Real_Name, useRealName: state.settings.UI_Use_Real_Name,

View File

@ -185,6 +185,8 @@ class SettingsView extends React.Component {
<List.Separator /> <List.Separator />
</List.Section> </List.Section>
<List.Section> <List.Section>
<List.Separator />
<List.Item title='Display' onPress={() => this.navigateToScreen('DisplayPrefsView')} showActionIndicator />
<List.Separator /> <List.Separator />
<List.Item <List.Item
title='Profile' title='Profile'

View File

@ -193,6 +193,13 @@ class Sidebar extends Component {
testID='sidebar-profile' testID='sidebar-profile'
current={this.currentItemKey === 'ProfileStackNavigator'} current={this.currentItemKey === 'ProfileStackNavigator'}
/> />
<SidebarItem
text={I18n.t('Display')}
left={<CustomIcon name='sort' size={20} color={themes[theme].titleText} />}
onPress={() => this.sidebarNavigate('DisplayPrefStackNavigator')}
testID='sidebar-display'
current={this.currentItemKey === 'DisplayPrefStackNavigator'}
/>
<SidebarItem <SidebarItem
text={I18n.t('Settings')} text={I18n.t('Settings')}
left={<CustomIcon name='administration' size={20} color={themes[theme].titleText} />} left={<CustomIcon name='administration' size={20} color={themes[theme].titleText} />}

View File

@ -61,7 +61,9 @@ class TeamChannelsView extends React.Component {
deleteCPermission: PropTypes.array, deleteCPermission: PropTypes.array,
deletePPermission: PropTypes.array, deletePPermission: PropTypes.array,
showActionSheet: PropTypes.func, showActionSheet: PropTypes.func,
deleteRoom: PropTypes.func deleteRoom: PropTypes.func,
showAvatar: PropTypes.bool,
displayMode: PropTypes.string
}; };
constructor(props) { constructor(props) {
@ -463,7 +465,7 @@ class TeamChannelsView extends React.Component {
}; };
renderItem = ({ item }) => { renderItem = ({ item }) => {
const { StoreLastMessage, useRealName, theme, width } = this.props; const { StoreLastMessage, useRealName, theme, width, showAvatar, displayMode } = this.props;
return ( return (
<RoomItem <RoomItem
item={item} item={item}
@ -478,6 +480,8 @@ class TeamChannelsView extends React.Component {
getRoomAvatar={this.getRoomAvatar} getRoomAvatar={this.getRoomAvatar}
swipeEnabled={false} swipeEnabled={false}
autoJoin={item.teamDefault} autoJoin={item.teamDefault}
showAvatar={showAvatar}
displayMode={displayMode}
/> />
); );
}; };
@ -540,7 +544,9 @@ const mapStateToProps = state => ({
editTeamChannelPermission: state.permissions[PERMISSION_EDIT_TEAM_CHANNEL], editTeamChannelPermission: state.permissions[PERMISSION_EDIT_TEAM_CHANNEL],
removeTeamChannelPermission: state.permissions[PERMISSION_REMOVE_TEAM_CHANNEL], removeTeamChannelPermission: state.permissions[PERMISSION_REMOVE_TEAM_CHANNEL],
deleteCPermission: state.permissions[PERMISSION_DELETE_C], deleteCPermission: state.permissions[PERMISSION_DELETE_C],
deletePPermission: state.permissions[PERMISSION_DELETE_P] deletePPermission: state.permissions[PERMISSION_DELETE_P],
showAvatar: state.sortPreferences.showAvatar,
displayMode: state.sortPreferences.displayMode
}); });
const mapDispatchToProps = dispatch => ({ const mapDispatchToProps = dispatch => ({

View File

@ -1,6 +1,5 @@
import React from 'react'; import React from 'react';
import { StyleSheet, Text, View } from 'react-native'; import { StyleSheet, Text, View } from 'react-native';
import PropTypes from 'prop-types';
import { createImageProgress } from 'react-native-image-progress'; import { createImageProgress } from 'react-native-image-progress';
import * as Progress from 'react-native-progress'; import * as Progress from 'react-native-progress';
import FastImage from '@rocket.chat/react-native-fast-image'; import FastImage from '@rocket.chat/react-native-fast-image';
@ -41,15 +40,24 @@ const styles = StyleSheet.create({
} }
}); });
const getInitial = url => url && url.replace(/http(s?):\/\//, '').slice(0, 1); const getInitial = (url: string) => url && url.replace(/http(s?):\/\//, '').slice(0, 1);
const Fallback = ({ theme, initial }) => ( interface IFallback {
theme: string;
initial: string;
}
const Fallback = ({ theme, initial }: IFallback) => (
<View style={[styles.container, styles.fallback, { backgroundColor: themes[theme].dangerColor }]}> <View style={[styles.container, styles.fallback, { backgroundColor: themes[theme].dangerColor }]}>
<Text style={[styles.initial, { color: themes[theme].buttonText }]}>{initial}</Text> <Text style={[styles.initial, { color: themes[theme].buttonText }]}>{initial}</Text>
</View> </View>
); );
const ServerAvatar = React.memo(({ theme, url, image }) => ( interface IServerAvatar {
theme: string;
url: string;
image: string;
}
const ServerAvatar = React.memo(({ theme, url, image }: IServerAvatar) => (
<View style={styles.container}> <View style={styles.container}>
{image && ( {image && (
<ImageProgress <ImageProgress
@ -66,16 +74,6 @@ const ServerAvatar = React.memo(({ theme, url, image }) => (
</View> </View>
)); ));
ServerAvatar.propTypes = {
theme: PropTypes.string,
url: PropTypes.string,
image: PropTypes.string
};
ServerAvatar.displayName = 'ServerAvatar'; ServerAvatar.displayName = 'ServerAvatar';
Fallback.propTypes = {
theme: PropTypes.string,
initial: PropTypes.string
};
export default ServerAvatar; export default ServerAvatar;

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Text, View } from 'react-native'; import { Text, View } from 'react-native';
import PropTypes from 'prop-types'; import { StackNavigationProp, StackNavigationOptions } from '@react-navigation/stack';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import I18n from '../../i18n'; import I18n from '../../i18n';
@ -12,23 +12,27 @@ import { getShowLoginButton } from '../../selectors/login';
import ServerAvatar from './ServerAvatar'; import ServerAvatar from './ServerAvatar';
import styles from './styles'; import styles from './styles';
class WorkspaceView extends React.Component { interface IWorkSpaceProp {
static navigationOptions = () => ({ // TODO: waiting for the RootStackParamList https://reactnavigation.org/docs/typescript/#type-checking-screens
title: I18n.t('Your_workspace') navigation: StackNavigationProp<any, 'WorkspaceView'>;
}); theme: string;
Site_Name: string;
Site_Url: string;
server: string;
Assets_favicon_512: {
url?: string;
defaultUrl: string;
};
registrationForm: string;
registrationText: string;
showLoginButton: boolean;
Accounts_iframe_enabled: boolean;
inviteLinkToken: string;
}
static propTypes = { class WorkspaceView extends React.Component<IWorkSpaceProp, any> {
navigation: PropTypes.object, static navigationOptions: StackNavigationOptions = {
theme: PropTypes.string, title: I18n.t('Your_workspace')
Site_Name: PropTypes.string,
Site_Url: PropTypes.string,
server: PropTypes.string,
Assets_favicon_512: PropTypes.object,
registrationForm: PropTypes.string,
registrationText: PropTypes.string,
showLoginButton: PropTypes.bool,
Accounts_iframe_enabled: PropTypes.bool,
inviteLinkToken: PropTypes.string
}; };
get showRegistrationButton() { get showRegistrationButton() {
@ -94,7 +98,7 @@ class WorkspaceView extends React.Component {
} }
} }
const mapStateToProps = state => ({ const mapStateToProps = (state: any) => ({
server: state.server.server, server: state.server.server,
Site_Name: state.settings.Site_Name, Site_Name: state.settings.Site_Name,
Site_Url: state.settings.Site_Url, Site_Url: state.settings.Site_Url,

View File

@ -1,6 +1,6 @@
module.exports = { module.exports = {
presets: ['module:metro-react-native-babel-preset'], presets: ['module:metro-react-native-babel-preset'],
plugins: [['@babel/plugin-proposal-decorators', { legacy: true }]], plugins: [['@babel/plugin-proposal-decorators', { legacy: true }], 'react-native-reanimated/plugin'],
env: { env: {
production: { production: {
plugins: ['transform-remove-console'] plugins: ['transform-remove-console']

View File

@ -0,0 +1,96 @@
const { login, navigateToLogin } = require('../../helpers/app');
const data = require('../../data');
const goToDisplayPref = async () => {
await expect(element(by.id('rooms-list-view-sidebar'))).toBeVisible();
await element(by.id('rooms-list-view-sidebar')).tap();
await expect(element(by.id('sidebar-display'))).toBeVisible();
await element(by.id('sidebar-display')).tap();
};
const goToRoomList = async () => {
await expect(element(by.id('display-view-drawer'))).toBeVisible();
await element(by.id('display-view-drawer')).tap();
await expect(element(by.id('sidebar-chats'))).toBeVisible();
await element(by.id('sidebar-chats')).tap();
};
describe('Rooms list screen', () => {
before(async () => {
await device.launchApp({ permissions: { notifications: 'YES' }, newInstance: true, delete: true });
await navigateToLogin();
await login(data.users.regular.username, data.users.regular.password);
});
describe('Render', () => {
it('should have rooms list screen', async () => {
await expect(element(by.id('rooms-list-view'))).toBeVisible();
});
it('should have room item', async () => {
await expect(element(by.id('rooms-list-view-item-general'))).toExist();
});
// Render - Header
describe('Header', () => {
it('should have create channel button', async () => {
await expect(element(by.id('rooms-list-view-create-channel'))).toBeVisible();
});
it('should have sidebar button', async () => {
await expect(element(by.id('rooms-list-view-sidebar'))).toBeVisible();
});
});
describe('DisplayPrefView', () => {
it('should go to Display Preferences', async () => {
await goToDisplayPref();
});
it('should have Displays button, expanded, condensed, avatars', async () => {
await expect(element(by.id('display-pref-view-expanded'))).toBeVisible();
await expect(element(by.id('display-pref-view-condensed'))).toBeVisible();
await expect(element(by.id('display-pref-view-avatars'))).toBeVisible();
});
it('should have Sort By button', async () => {
await expect(element(by.id('display-pref-view-activity'))).toBeVisible();
await expect(element(by.id('display-pref-view-name'))).toBeVisible();
});
it('should have Group by button', async () => {
await expect(element(by.id('display-pref-view-unread'))).toBeVisible();
await expect(element(by.id('display-pref-view-favorites'))).toBeVisible();
await expect(element(by.id('display-pref-view-types'))).toBeVisible();
});
});
describe('Change display', () => {
it('should appear the last message in RoomList when is Expanded', async () => {
await element(by.id('display-pref-view-expanded')).tap();
await goToRoomList();
await expect(element(by.id('room-item-last-message')).atIndex(0)).toBeVisible();
});
it('should not appear the last message in RoomList when is Condensed', async () => {
await goToDisplayPref();
await element(by.id('display-pref-view-condensed')).tap();
await goToRoomList();
await expect(element(by.id('room-item-last-message'))).not.toBeVisible();
});
});
describe('Change the avatar visible', () => {
it('should have avatar as default in room list', async () => {
await expect(element(by.id('avatar')).atIndex(0)).toExist();
});
it('should hide the avatar', async () => {
await goToDisplayPref();
await expect(element(by.id('display-pref-view-avatar-switch'))).toBeVisible();
await element(by.id('display-pref-view-avatar-switch')).tap();
await goToRoomList();
await expect(element(by.id('avatar'))).not.toBeVisible();
});
});
});
});

View File

@ -7,3 +7,10 @@
#import <react-native-simple-crypto/Aes.h> #import <react-native-simple-crypto/Aes.h>
#import <react-native-simple-crypto/Rsa.h> #import <react-native-simple-crypto/Rsa.h>
#import <react-native-simple-crypto/Shared.h> #import <react-native-simple-crypto/Shared.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <React/RCTViewManager.h>
#import <React/RCTBridgeModule.h>
// Silence warning
#import "../../node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/SupportingFiles/Bridging.h"

View File

@ -4,6 +4,9 @@ require_relative '../node_modules/@react-native-community/cli-platform-ios/nativ
require_relative '../node_modules/react-native-unimodules/cocoapods.rb' require_relative '../node_modules/react-native-unimodules/cocoapods.rb'
def all_pods def all_pods
pod 'WatermelonDB', :path => '../node_modules/@nozbe/watermelondb'
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi', :modular_headers => true
pod 'simdjson', path: '../node_modules/@nozbe/simdjson'
config = use_native_modules! config = use_native_modules!
use_unimodules! use_unimodules!
use_react_native!( use_react_native!(

View File

@ -530,19 +530,46 @@ PODS:
- RNFBApp - RNFBApp
- RNGestureHandler (1.10.3): - RNGestureHandler (1.10.3):
- React-Core - React-Core
- RNImageCropPicker (0.31.1): - RNImageCropPicker (0.36.3):
- React-Core - React-Core
- React-RCTImage - React-RCTImage
- RNImageCropPicker/QBImagePickerController (= 0.31.1) - RNImageCropPicker/QBImagePickerController (= 0.36.3)
- TOCropViewController - TOCropViewController
- RNImageCropPicker/QBImagePickerController (0.31.1): - RNImageCropPicker/QBImagePickerController (0.36.3):
- React-Core - React-Core
- React-RCTImage - React-RCTImage
- TOCropViewController - TOCropViewController
- RNLocalize (2.1.1): - RNLocalize (2.1.1):
- React-Core - React-Core
- RNReanimated (1.9.0): - RNReanimated (2.2.2):
- DoubleConversion
- FBLazyVector
- FBReactNativeSpec
- glog
- RCT-Folly
- RCTRequired
- RCTTypeSafety
- React - React
- React-callinvoker
- React-Core
- React-Core/DevSupport
- React-Core/RCTWebSocket
- React-CoreModules
- React-cxxreact
- React-jsi
- React-jsiexecutor
- React-jsinspector
- React-RCTActionSheet
- React-RCTAnimation
- React-RCTBlob
- React-RCTImage
- React-RCTLinking
- React-RCTNetwork
- React-RCTSettings
- React-RCTText
- React-RCTVibration
- ReactCommon/turbomodule/core
- Yoga
- RNRootView (1.0.3): - RNRootView (1.0.3):
- React - React
- RNScreens (2.9.0): - RNScreens (2.9.0):
@ -555,6 +582,7 @@ PODS:
- SDWebImageWebPCoder (0.4.1): - SDWebImageWebPCoder (0.4.1):
- libwebp (~> 1.0) - libwebp (~> 1.0)
- SDWebImage/Core (~> 5.5) - SDWebImage/Core (~> 5.5)
- simdjson (0.9.6-fix2)
- TOCropViewController (2.5.3) - TOCropViewController (2.5.3)
- UMAppLoader (1.2.0) - UMAppLoader (1.2.0)
- UMBarCodeScannerInterface (5.2.1) - UMBarCodeScannerInterface (5.2.1)
@ -573,6 +601,9 @@ PODS:
- UMFontInterface - UMFontInterface
- UMSensorsInterface (5.2.1) - UMSensorsInterface (5.2.1)
- UMTaskManagerInterface (5.2.1) - UMTaskManagerInterface (5.2.1)
- WatermelonDB (0.23.0):
- React
- React-jsi
- Yoga (1.14.0) - Yoga (1.14.0)
- YogaKit (1.18.1): - YogaKit (1.18.1):
- Yoga (~> 1.14) - Yoga (~> 1.14)
@ -681,6 +712,7 @@ DEPENDENCIES:
- RNRootView (from `../node_modules/rn-root-view`) - RNRootView (from `../node_modules/rn-root-view`)
- RNScreens (from `../node_modules/react-native-screens`) - RNScreens (from `../node_modules/react-native-screens`)
- RNVectorIcons (from `../node_modules/react-native-vector-icons`) - RNVectorIcons (from `../node_modules/react-native-vector-icons`)
- "simdjson (from `../node_modules/@nozbe/simdjson`)"
- UMAppLoader (from `../node_modules/unimodules-app-loader/ios`) - UMAppLoader (from `../node_modules/unimodules-app-loader/ios`)
- UMBarCodeScannerInterface (from `../node_modules/unimodules-barcode-scanner-interface/ios`) - UMBarCodeScannerInterface (from `../node_modules/unimodules-barcode-scanner-interface/ios`)
- UMCameraInterface (from `../node_modules/unimodules-camera-interface/ios`) - UMCameraInterface (from `../node_modules/unimodules-camera-interface/ios`)
@ -694,6 +726,7 @@ DEPENDENCIES:
- "UMReactNativeAdapter (from `../node_modules/@unimodules/react-native-adapter/ios`)" - "UMReactNativeAdapter (from `../node_modules/@unimodules/react-native-adapter/ios`)"
- UMSensorsInterface (from `../node_modules/unimodules-sensors-interface/ios`) - UMSensorsInterface (from `../node_modules/unimodules-sensors-interface/ios`)
- UMTaskManagerInterface (from `../node_modules/unimodules-task-manager-interface/ios`) - UMTaskManagerInterface (from `../node_modules/unimodules-task-manager-interface/ios`)
- "WatermelonDB (from `../node_modules/@nozbe/watermelondb`)"
- Yoga (from `../node_modules/react-native/ReactCommon/yoga`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`)
SPEC REPOS: SPEC REPOS:
@ -889,6 +922,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-screens" :path: "../node_modules/react-native-screens"
RNVectorIcons: RNVectorIcons:
:path: "../node_modules/react-native-vector-icons" :path: "../node_modules/react-native-vector-icons"
simdjson:
:path: "../node_modules/@nozbe/simdjson"
UMAppLoader: UMAppLoader:
:path: "../node_modules/unimodules-app-loader/ios" :path: "../node_modules/unimodules-app-loader/ios"
UMBarCodeScannerInterface: UMBarCodeScannerInterface:
@ -915,6 +950,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/unimodules-sensors-interface/ios" :path: "../node_modules/unimodules-sensors-interface/ios"
UMTaskManagerInterface: UMTaskManagerInterface:
:path: "../node_modules/unimodules-task-manager-interface/ios" :path: "../node_modules/unimodules-task-manager-interface/ios"
WatermelonDB:
:path: "../node_modules/@nozbe/watermelondb"
Yoga: Yoga:
:path: "../node_modules/react-native/ReactCommon/yoga" :path: "../node_modules/react-native/ReactCommon/yoga"
@ -940,7 +977,7 @@ SPEC CHECKSUMS:
EXVideoThumbnails: cd257fc6e07884a704a5674d362a6410933acb68 EXVideoThumbnails: cd257fc6e07884a704a5674d362a6410933acb68
EXWebBrowser: d37a5ffdea1b65947352bc001dd9f732463725d4 EXWebBrowser: d37a5ffdea1b65947352bc001dd9f732463725d4
FBLazyVector: e686045572151edef46010a6f819ade377dfeb4b FBLazyVector: e686045572151edef46010a6f819ade377dfeb4b
FBReactNativeSpec: b427d2f482828b9533661dbcf9edf846cb60dc7b FBReactNativeSpec: 110d69378fce79af38271c39894b59fec7890221
Firebase: 919186c8e119dd9372a45fd1dd17a8a942bc1892 Firebase: 919186c8e119dd9372a45fd1dd17a8a942bc1892
FirebaseAnalytics: 5fa308e1b13f838d0f6dc74719ac2a72e8c5afc4 FirebaseAnalytics: 5fa308e1b13f838d0f6dc74719ac2a72e8c5afc4
FirebaseCore: 8cd4f8ea22075e0ee582849b1cf79d8816506085 FirebaseCore: 8cd4f8ea22075e0ee582849b1cf79d8816506085
@ -1024,14 +1061,15 @@ SPEC CHECKSUMS:
RNFBApp: 6fd8a7e757135d4168bf033a8812c241af7363a0 RNFBApp: 6fd8a7e757135d4168bf033a8812c241af7363a0
RNFBCrashlytics: 88de72c2476b5868a892d9523b89b86c527c540e RNFBCrashlytics: 88de72c2476b5868a892d9523b89b86c527c540e
RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211 RNGestureHandler: a479ebd5ed4221a810967000735517df0d2db211
RNImageCropPicker: 38865ab4af1b0b2146ad66061196bc0184946855 RNImageCropPicker: 97289cd94fb01ab79db4e5c92938be4d0d63415d
RNLocalize: 82a569022724d35461e2dc5b5d015a13c3ca995b RNLocalize: 82a569022724d35461e2dc5b5d015a13c3ca995b
RNReanimated: b5ccb50650ba06f6e749c7c329a1bc3ae0c88b43 RNReanimated: 241c586663f44f19a53883c63375fdd041253960
RNRootView: 895a4813dedeaca82db2fa868ca1c333d790e494 RNRootView: 895a4813dedeaca82db2fa868ca1c333d790e494
RNScreens: c526239bbe0e957b988dacc8d75ac94ec9cb19da RNScreens: c526239bbe0e957b988dacc8d75ac94ec9cb19da
RNVectorIcons: 31cebfcf94e8cf8686eb5303ae0357da64d7a5a4 RNVectorIcons: 31cebfcf94e8cf8686eb5303ae0357da64d7a5a4
SDWebImage: cf6922231e95550934da2ada0f20f2becf2ceba9 SDWebImage: cf6922231e95550934da2ada0f20f2becf2ceba9
SDWebImageWebPCoder: 36f8f47bd9879a8aea6044765c1351120fd8e3a8 SDWebImageWebPCoder: 36f8f47bd9879a8aea6044765c1351120fd8e3a8
simdjson: 85016870cd17207312b718ef6652eb6a1cd6a2b0
TOCropViewController: 20a14b6a7a098308bf369e7c8d700dc983a974e6 TOCropViewController: 20a14b6a7a098308bf369e7c8d700dc983a974e6
UMAppLoader: 61049c8d55590b74e9ae1d5429bf68d96b4a2528 UMAppLoader: 61049c8d55590b74e9ae1d5429bf68d96b4a2528
UMBarCodeScannerInterface: e5e4c87797d3d01214e25cd1618866caf5d4f17f UMBarCodeScannerInterface: e5e4c87797d3d01214e25cd1618866caf5d4f17f
@ -1046,9 +1084,10 @@ SPEC CHECKSUMS:
UMReactNativeAdapter: 538efe92e781b5d7678cf95b34c46f2d0989a557 UMReactNativeAdapter: 538efe92e781b5d7678cf95b34c46f2d0989a557
UMSensorsInterface: cb5bf31d52c4349f0ff9e3c049bbe4df0d80d383 UMSensorsInterface: cb5bf31d52c4349f0ff9e3c049bbe4df0d80d383
UMTaskManagerInterface: 80653f25c55d9e6d79d6a0a65589fa213feaee11 UMTaskManagerInterface: 80653f25c55d9e6d79d6a0a65589fa213feaee11
WatermelonDB: 577c61fceff16e9f9103b59d14aee4850c0307b6
Yoga: 575c581c63e0d35c9a83f4b46d01d63abc1100ac Yoga: 575c581c63e0d35c9a83f4b46d01d63abc1100ac
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: 2cb6f38193d69310b4dfc466be3cf4ff7a5e98d3 PODFILE CHECKSUM: 46fb1ed324f44252f8900c63e7c93e4391658bad
COCOAPODS: 1.10.1 COCOAPODS: 1.10.1

View File

@ -24,7 +24,6 @@
1E068CFF24FD2DC700A0FFC1 /* AppGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E068CFD24FD2DC700A0FFC1 /* AppGroup.swift */; }; 1E068CFF24FD2DC700A0FFC1 /* AppGroup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E068CFD24FD2DC700A0FFC1 /* AppGroup.swift */; };
1E068D0124FD2E0500A0FFC1 /* AppGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E068D0024FD2E0500A0FFC1 /* AppGroup.m */; }; 1E068D0124FD2E0500A0FFC1 /* AppGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E068D0024FD2E0500A0FFC1 /* AppGroup.m */; };
1E068D0224FD2E0500A0FFC1 /* AppGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E068D0024FD2E0500A0FFC1 /* AppGroup.m */; }; 1E068D0224FD2E0500A0FFC1 /* AppGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 1E068D0024FD2E0500A0FFC1 /* AppGroup.m */; };
1E1C2F7E250FACB5005DCE7D /* libWatermelonDB.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7AAA749B23043AD300F1ADE9 /* libWatermelonDB.a */; };
1E1C2F80250FCB69005DCE7D /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E1C2F7F250FCB69005DCE7D /* Database.swift */; }; 1E1C2F80250FCB69005DCE7D /* Database.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E1C2F7F250FCB69005DCE7D /* Database.swift */; };
1E1EA80A2326CD2200E22452 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA8092326CD2200E22452 /* AVFoundation.framework */; }; 1E1EA80A2326CD2200E22452 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA8092326CD2200E22452 /* AVFoundation.framework */; };
1E1EA80C2326CD2800E22452 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA80B2326CD2800E22452 /* AudioToolbox.framework */; }; 1E1EA80C2326CD2800E22452 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E1EA80B2326CD2800E22452 /* AudioToolbox.framework */; };
@ -43,7 +42,6 @@
1E470E832513A71E00E3DD1D /* RocketChat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E470E822513A71E00E3DD1D /* RocketChat.swift */; }; 1E470E832513A71E00E3DD1D /* RocketChat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E470E822513A71E00E3DD1D /* RocketChat.swift */; };
1E51D962251263CD00DC95DE /* MessageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E51D961251263CD00DC95DE /* MessageType.swift */; }; 1E51D962251263CD00DC95DE /* MessageType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E51D961251263CD00DC95DE /* MessageType.swift */; };
1E51D965251263D600DC95DE /* NotificationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E51D964251263D600DC95DE /* NotificationType.swift */; }; 1E51D965251263D600DC95DE /* NotificationType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E51D964251263D600DC95DE /* NotificationType.swift */; };
1E55FDB32320675C0048D2F9 /* libWatermelonDB.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 7AAA749B23043AD300F1ADE9 /* libWatermelonDB.a */; };
1E598AE42515057D002BDFBD /* Date+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E598AE32515057D002BDFBD /* Date+Extensions.swift */; }; 1E598AE42515057D002BDFBD /* Date+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E598AE32515057D002BDFBD /* Date+Extensions.swift */; };
1E598AE725150660002BDFBD /* Data+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E598AE625150660002BDFBD /* Data+Extensions.swift */; }; 1E598AE725150660002BDFBD /* Data+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E598AE625150660002BDFBD /* Data+Extensions.swift */; };
1E598AE925151A63002BDFBD /* SendMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E598AE825151A63002BDFBD /* SendMessage.swift */; }; 1E598AE925151A63002BDFBD /* SendMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1E598AE825151A63002BDFBD /* SendMessage.swift */; };
@ -158,13 +156,6 @@
remoteGlobalIDString = 1EFEB5942493B6640072EDC0; remoteGlobalIDString = 1EFEB5942493B6640072EDC0;
remoteInfo = NotificationService; remoteInfo = NotificationService;
}; };
7AAA749A23043AD300F1ADE9 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 290E43E48AD8418287FA99D6 /* WatermelonDB.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 6E660D5E213BCCD300189354;
remoteInfo = WatermelonDB;
};
7AAB3E0F257E6A6E00707CF6 /* PBXContainerItemProxy */ = { 7AAB3E0F257E6A6E00707CF6 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy; isa = PBXContainerItemProxy;
containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */; containerPortal = 83CBB9F71A601CBA00E9B192 /* Project object */;
@ -265,7 +256,6 @@
1EFEB5972493B6640072EDC0 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; }; 1EFEB5972493B6640072EDC0 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
1EFEB5992493B6640072EDC0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; 1EFEB5992493B6640072EDC0 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
1EFEB5A12493B67D0072EDC0 /* NotificationService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NotificationService.entitlements; sourceTree = "<group>"; }; 1EFEB5A12493B67D0072EDC0 /* NotificationService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = NotificationService.entitlements; sourceTree = "<group>"; };
290E43E48AD8418287FA99D6 /* WatermelonDB.xcodeproj */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "wrapper.pb-project"; name = WatermelonDB.xcodeproj; path = "../node_modules/@nozbe/watermelondb/native/ios/WatermelonDB.xcodeproj"; sourceTree = "<group>"; };
2977818A2C0F18284F485E2B /* Pods-defaults-Rocket.Chat.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-Rocket.Chat.release.xcconfig"; path = "Pods/Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat.release.xcconfig"; sourceTree = "<group>"; }; 2977818A2C0F18284F485E2B /* Pods-defaults-Rocket.Chat.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-Rocket.Chat.release.xcconfig"; path = "Pods/Target Support Files/Pods-defaults-Rocket.Chat/Pods-defaults-Rocket.Chat.release.xcconfig"; sourceTree = "<group>"; };
298C921C910A1A2FD60068AE /* Pods-defaults-RocketChatRN.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-RocketChatRN.debug.xcconfig"; path = "Pods/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN.debug.xcconfig"; sourceTree = "<group>"; }; 298C921C910A1A2FD60068AE /* Pods-defaults-RocketChatRN.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-defaults-RocketChatRN.debug.xcconfig"; path = "Pods/Target Support Files/Pods-defaults-RocketChatRN/Pods-defaults-RocketChatRN.debug.xcconfig"; sourceTree = "<group>"; };
2B2C0164CCC5BED03F5A257E /* libPods-defaults-NotificationService.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-defaults-NotificationService.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 2B2C0164CCC5BED03F5A257E /* libPods-defaults-NotificationService.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-defaults-NotificationService.a"; sourceTree = BUILT_PRODUCTS_DIR; };
@ -321,7 +311,6 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
1E55FDB32320675C0048D2F9 /* libWatermelonDB.a in Frameworks */,
1E25743422CBA2CF005A877F /* JavaScriptCore.framework in Frameworks */, 1E25743422CBA2CF005A877F /* JavaScriptCore.framework in Frameworks */,
DC5529EC3B4695AC7319279F /* libPods-defaults-ShareRocketChatRN.a in Frameworks */, DC5529EC3B4695AC7319279F /* libPods-defaults-ShareRocketChatRN.a in Frameworks */,
); );
@ -331,7 +320,6 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
1E1C2F7E250FACB5005DCE7D /* libWatermelonDB.a in Frameworks */,
EDE8A8F63A3ADB93A6640F8E /* libPods-defaults-NotificationService.a in Frameworks */, EDE8A8F63A3ADB93A6640F8E /* libPods-defaults-NotificationService.a in Frameworks */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -503,18 +491,9 @@
name = Pods; name = Pods;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
7AAA749723043AD300F1ADE9 /* Products */ = {
isa = PBXGroup;
children = (
7AAA749B23043AD300F1ADE9 /* libWatermelonDB.a */,
);
name = Products;
sourceTree = "<group>";
};
832341AE1AAA6A7D00B99B32 /* Libraries */ = { 832341AE1AAA6A7D00B99B32 /* Libraries */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
290E43E48AD8418287FA99D6 /* WatermelonDB.xcodeproj */,
); );
name = Libraries; name = Libraries;
sourceTree = "<group>"; sourceTree = "<group>";
@ -747,12 +726,6 @@
mainGroup = 83CBB9F61A601CBA00E9B192; mainGroup = 83CBB9F61A601CBA00E9B192;
productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */;
projectDirPath = ""; projectDirPath = "";
projectReferences = (
{
ProductGroup = 7AAA749723043AD300F1ADE9 /* Products */;
ProjectRef = 290E43E48AD8418287FA99D6 /* WatermelonDB.xcodeproj */;
},
);
projectRoot = ""; projectRoot = "";
targets = ( targets = (
13B07F861A680F5B00A75B9A /* RocketChatRN */, 13B07F861A680F5B00A75B9A /* RocketChatRN */,
@ -763,16 +736,6 @@
}; };
/* End PBXProject section */ /* End PBXProject section */
/* Begin PBXReferenceProxy section */
7AAA749B23043AD300F1ADE9 /* libWatermelonDB.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = libWatermelonDB.a;
remoteRef = 7AAA749A23043AD300F1ADE9 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */ /* Begin PBXResourcesBuildPhase section */
13B07F8E1A680F5B00A75B9A /* Resources */ = { 13B07F8E1A680F5B00A75B9A /* Resources */ = {
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
@ -1726,7 +1689,7 @@
INFOPLIST_FILE = NotificationService/Info.plist; INFOPLIST_FILE = NotificationService/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 11.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.20.0; MARKETING_VERSION = 4.21.0;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = chat.rocket.reactnative.NotificationService; PRODUCT_BUNDLE_IDENTIFIER = chat.rocket.reactnative.NotificationService;
@ -1763,7 +1726,7 @@
INFOPLIST_FILE = NotificationService/Info.plist; INFOPLIST_FILE = NotificationService/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 11.0; IPHONEOS_DEPLOYMENT_TARGET = 11.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.20.0; MARKETING_VERSION = 4.21.0;
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
PRODUCT_BUNDLE_IDENTIFIER = chat.rocket.reactnative.NotificationService; PRODUCT_BUNDLE_IDENTIFIER = chat.rocket.reactnative.NotificationService;
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";

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.20.0</string> <string>4.21.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.20.0</string> <string>4.21.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.20.0", "version": "4.21.0",
"private": true, "private": true,
"scripts": { "scripts": {
"start": "react-native start", "start": "react-native start",
@ -29,7 +29,7 @@
"dependencies": { "dependencies": {
"@bugsnag/react-native": "^7.10.5", "@bugsnag/react-native": "^7.10.5",
"@codler/react-native-keyboard-aware-scroll-view": "^1.0.1", "@codler/react-native-keyboard-aware-scroll-view": "^1.0.1",
"@nozbe/watermelondb": "0.19.0", "@nozbe/watermelondb": "0.23.0",
"@react-native-community/art": "^1.2.0", "@react-native-community/art": "^1.2.0",
"@react-native-community/async-storage": "1.12.1", "@react-native-community/async-storage": "1.12.1",
"@react-native-community/blur": "^3.6.0", "@react-native-community/blur": "^3.6.0",
@ -56,7 +56,6 @@
"commonmark-react-renderer": "git+https://github.com/RocketChat/commonmark-react-renderer.git", "commonmark-react-renderer": "git+https://github.com/RocketChat/commonmark-react-renderer.git",
"dequal": "^2.0.2", "dequal": "^2.0.2",
"ejson": "2.2.1", "ejson": "2.2.1",
"eslint-config-airbnb": "^18.1.0",
"expo-apple-authentication": "^2.2.1", "expo-apple-authentication": "^2.2.1",
"expo-av": "8.2.1", "expo-av": "8.2.1",
"expo-file-system": "9.0.1", "expo-file-system": "9.0.1",
@ -104,7 +103,7 @@
"react-native-popover-view": "4.0.1", "react-native-popover-view": "4.0.1",
"react-native-progress": "4.1.2", "react-native-progress": "4.1.2",
"react-native-prompt-android": "^1.1.0", "react-native-prompt-android": "^1.1.0",
"react-native-reanimated": "1.9.0", "react-native-reanimated": "2.2.2",
"react-native-restart": "0.0.22", "react-native-restart": "0.0.22",
"react-native-safe-area-context": "3.2.0", "react-native-safe-area-context": "3.2.0",
"react-native-screens": "2.9.0", "react-native-screens": "2.9.0",

View File

@ -1,9 +1,32 @@
diff --git a/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt b/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt
index 802f137..cfcac91 100644
--- a/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt
+++ b/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt
@@ -8,7 +8,7 @@ import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteQuery
import java.io.File
-class Database(private val name: String, private val context: Context) {
+public class Database(private val name: String, private val context: Context) {
private val db: SQLiteDatabase by lazy {
SQLiteDatabase.openOrCreateDatabase(
@@ -44,7 +44,7 @@ class Database(private val name: String, private val context: Context) {
fun delete(query: SQL, args: QueryArgs) = db.execSQL(query, args)
- fun rawQuery(sql: SQL, args: QueryArgs = emptyArray()): Cursor {
+ public fun rawQuery(sql: SQL, args: QueryArgs = emptyArray()): Cursor {
// HACK: db.rawQuery only supports String args, and there's no clean way AFAIK to construct
// a query with arbitrary args (like with execSQL). However, we can misuse cursor factory
// to get the reference of a SQLiteQuery before it's executed
diff --git a/node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/Database.swift b/node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/Database.swift diff --git a/node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/Database.swift b/node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/Database.swift
index 43f2c9c..e24a24f 100644 index b4d7151..429e318 100644
--- a/node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/Database.swift --- a/node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/Database.swift
+++ b/node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/Database.swift +++ b/node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/Database.swift
@@ -1,14 +1,14 @@ @@ -1,15 +1,15 @@
import Foundation import Foundation
import SQLite3
-class Database { -class Database {
- typealias SQL = String - typealias SQL = String
@ -22,7 +45,7 @@ index 43f2c9c..e24a24f 100644
self.path = path self.path = path
fmdb = FMDatabase(path: path) fmdb = FMDatabase(path: path)
open() open()
@@ -53,7 +53,7 @@ class Database { @@ -54,7 +54,7 @@ class Database {
} }
} }
@ -31,38 +54,3 @@ index 43f2c9c..e24a24f 100644
let resultSet = try fmdb.executeQuery(query, values: args) let resultSet = try fmdb.executeQuery(query, values: args)
return AnyIterator { return AnyIterator {
diff --git a/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt b/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt
index 2217222..5b2eb73 100644
--- a/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt
+++ b/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt
@@ -5,7 +5,7 @@ import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import java.io.File
-class Database(private val name: String, private val context: Context) {
+public class Database(private val name: String, private val context: Context) {
private val db: SQLiteDatabase by lazy {
SQLiteDatabase.openOrCreateDatabase(
@@ -41,7 +41,7 @@ class Database(private val name: String, private val context: Context) {
fun delete(query: SQL, args: QueryArgs) = db.execSQL(query, args)
- fun rawQuery(query: SQL, args: RawQueryArgs = emptyArray()): Cursor = db.rawQuery(query, args)
+ public fun rawQuery(query: SQL, args: RawQueryArgs = emptyArray()): Cursor = db.rawQuery(query, args)
fun count(query: SQL, args: RawQueryArgs = emptyArray()): Int =
rawQuery(query, args).use {
diff --git a/node_modules/@nozbe/watermelondb/decorators/date/index.js b/node_modules/@nozbe/watermelondb/decorators/date/index.js
index 65690af..ce71aa0 100644
--- a/node_modules/@nozbe/watermelondb/decorators/date/index.js
+++ b/node_modules/@nozbe/watermelondb/decorators/date/index.js
@@ -44,7 +44,7 @@ var dateDecorator = (0, _makeDecorator.default)(function (columnName) {
var rawValue = date ? +new Date(date) : null;
if (rawValue && date) {
- cache.set(rawValue, date);
+ cache.set(rawValue, new Date(date));
}
this.asModel._setRaw(columnName, rawValue);

View File

@ -1,12 +0,0 @@
diff --git a/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java b/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java
index 3500542..94e45b6 100644
--- a/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java
+++ b/node_modules/react-native-image-crop-picker/android/src/main/java/com/reactnative/ivpusic/imagepicker/PickerModule.java
@@ -584,6 +584,7 @@ class PickerModule extends ReactContextBaseJavaModule implements ActivityEventLi
image.putInt("height", options.outHeight);
image.putString("mime", options.outMimeType);
image.putInt("size", (int) new File(compressedImagePath).length());
+ image.putString("filename", compressedImage.getName());
image.putString("modificationDate", String.valueOf(modificationDate));
if (includeBase64) {

File diff suppressed because it is too large Load Diff

View File

@ -5,12 +5,6 @@ module.exports = {
android: null android: null
} }
}, },
'@nozbe/watermelondb': {
platforms: {
android: null,
ios: null
}
},
'@react-native-firebase/app': { '@react-native-firebase/app': {
platforms: { platforms: {
android: null android: null

View File

@ -7,6 +7,7 @@ import { Provider } from 'react-redux';
import { themes } from '../../app/constants/colors'; import { themes } from '../../app/constants/colors';
import RoomItemComponent from '../../app/presentation/RoomItem/RoomItem'; import RoomItemComponent from '../../app/presentation/RoomItem/RoomItem';
import { longText } from '../utils'; import { longText } from '../utils';
import { DISPLAY_MODE_CONDENSED, DISPLAY_MODE_EXPANDED } from '../../app/constants/constantDisplayMode';
import { store } from './index'; import { store } from './index';
const baseUrl = 'https://open.rocket.chat'; const baseUrl = 'https://open.rocket.chat';
@ -30,6 +31,8 @@ const RoomItem = props => (
baseUrl={baseUrl} baseUrl={baseUrl}
width={width} width={width}
theme={_theme} theme={_theme}
showAvatar
displayMode={DISPLAY_MODE_EXPANDED}
{...updatedAt} {...updatedAt}
{...props} {...props}
/> />
@ -126,3 +129,57 @@ stories.add('Last Message', () => (
<RoomItem showLastMessage alert tunread={[1]} lastMessage={lastMessage} /> <RoomItem showLastMessage alert tunread={[1]} lastMessage={lastMessage} />
</> </>
)); ));
stories.add('Condensed Room Item', () => (
<>
<RoomItem showLastMessage alert tunread={[1]} lastMessage={lastMessage} displayMode={DISPLAY_MODE_CONDENSED} />
<RoomItem showLastMessage alert name='unread' unread={1000} displayMode={DISPLAY_MODE_CONDENSED} />
<RoomItem type='c' displayMode={DISPLAY_MODE_CONDENSED} autoJoin />
</>
));
stories.add('Condensed Room Item without Avatar', () => (
<>
<RoomItem
showLastMessage
alert
tunread={[1]}
lastMessage={lastMessage}
displayMode={DISPLAY_MODE_CONDENSED}
showAvatar={false}
/>
<RoomItem type='p' displayMode={DISPLAY_MODE_CONDENSED} showAvatar={false} />
<RoomItem name={longText} autoJoin displayMode={DISPLAY_MODE_CONDENSED} showAvatar={false} />
</>
));
stories.add('Expanded Room Item without Avatar', () => (
<>
<RoomItem
showLastMessage
alert
tunread={[1]}
lastMessage={lastMessage}
displayMode={DISPLAY_MODE_EXPANDED}
showAvatar={false}
/>
<RoomItem
status='online'
showLastMessage
alert
tunread={[1]}
lastMessage={lastMessage}
displayMode={DISPLAY_MODE_EXPANDED}
showAvatar={false}
/>
<RoomItem
status='online'
showLastMessage
alert
lastMessage={lastMessage}
displayMode={DISPLAY_MODE_EXPANDED}
showAvatar={false}
/>
</>
));

130
yarn.lock
View File

@ -1428,6 +1428,13 @@
dependencies: dependencies:
"@babel/helper-plugin-utils" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3"
"@babel/plugin-transform-object-assign@^7.10.4":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-assign/-/plugin-transform-object-assign-7.14.5.tgz#62537d54b6d85de04f4df48bfdba2eebff17b760"
integrity sha512-lvhjk4UN9xJJYB1mI5KC0/o1D5EcJXdbhVe+4fSk08D6ZN+iuAIs7LJC+71h8av9Ew4+uRq9452v9R93SFmQlQ==
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/plugin-transform-object-super@^7.0.0", "@babel/plugin-transform-object-super@^7.14.5": "@babel/plugin-transform-object-super@^7.0.0", "@babel/plugin-transform-object-super@^7.14.5":
version "7.14.5" version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz#d0b5faeac9e98597a161a9cf78c527ed934cdc45" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz#d0b5faeac9e98597a161a9cf78c527ed934cdc45"
@ -1792,6 +1799,13 @@
dependencies: dependencies:
regenerator-runtime "^0.13.4" regenerator-runtime "^0.13.4"
"@babel/runtime@^7.11.2":
version "7.15.4"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a"
integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==
dependencies:
regenerator-runtime "^0.13.4"
"@babel/runtime@^7.12.1": "@babel/runtime@^7.12.1":
version "7.14.0" version "7.14.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6"
@ -2840,23 +2854,37 @@
"@nodelib/fs.scandir" "2.1.5" "@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0" fastq "^1.6.0"
"@nozbe/simdjson@0.9.6-fix2":
version "0.9.6-fix2"
resolved "https://registry.yarnpkg.com/@nozbe/simdjson/-/simdjson-0.9.6-fix2.tgz#00d1c8ec76bfac25c022b07511c8fff4568b2973"
integrity sha512-xKzrhtH7elBUOOihtNwN4Jr0iVcI7+95NCzC2gLvBYkITiCYqqOUm+2badFMkWFEE9gKQLUJJaux4qtgPPItaQ==
"@nozbe/sqlite@3.31.1": "@nozbe/sqlite@3.31.1":
version "3.31.1" version "3.31.1"
resolved "https://registry.yarnpkg.com/@nozbe/sqlite/-/sqlite-3.31.1.tgz#ffd394ad7c188c6b73f89fd6e1ccb849a1b96dba" resolved "https://registry.yarnpkg.com/@nozbe/sqlite/-/sqlite-3.31.1.tgz#ffd394ad7c188c6b73f89fd6e1ccb849a1b96dba"
integrity sha512-z5+GdcHZl9OQ1g0pnygORAnwCYUlYw/gQxdW/8rS0HxD2Gnn/k3DBQOvqQIH4Z3Z3KWVMbGUYhcH1v4SqTAdwg== integrity sha512-z5+GdcHZl9OQ1g0pnygORAnwCYUlYw/gQxdW/8rS0HxD2Gnn/k3DBQOvqQIH4Z3Z3KWVMbGUYhcH1v4SqTAdwg==
"@nozbe/watermelondb@0.19.0": "@nozbe/watermelondb@0.23.0":
version "0.19.0" version "0.23.0"
resolved "https://registry.yarnpkg.com/@nozbe/watermelondb/-/watermelondb-0.19.0.tgz#70dae4bfca9dde8d61819a6092846e178a50e2f7" resolved "https://registry.yarnpkg.com/@nozbe/watermelondb/-/watermelondb-0.23.0.tgz#505b1dda6445c734708d1af0d82b10b7fcc58c07"
integrity sha512-x7sclLu/4RDmLzANIYQioKjWdmoIxgqYw7OJnS7UtWEtJGn28l5Z69SWojll/RM0X2KOEem0BIcjqM46CA53GA== integrity sha512-nQCQCZe9jthWlVPDI5WfOPc9lx3hI+sxG74vlyDH3NXgzjJiLEkVmpV+zF71U6VQLHsFRE7pGntys4SdsuEmzg==
dependencies: dependencies:
"@babel/runtime" "^7.11.2"
"@nozbe/simdjson" "0.9.6-fix2"
"@nozbe/sqlite" "3.31.1" "@nozbe/sqlite" "3.31.1"
lokijs "npm:@nozbe/lokijs@1.5.10-wmelon0" "@nozbe/with-observables" "1.4.0"
rambdax "2.15.0" hoist-non-react-statics "^3.3.2"
rxjs "^6.2.2" lokijs "npm:@nozbe/lokijs@1.5.12-wmelon2"
rxjs-compat "^6.3.2" rxjs "^6.5.3"
sql-escape-string "^1.1.0" sql-escape-string "^1.1.0"
"@nozbe/with-observables@1.4.0":
version "1.4.0"
resolved "https://registry.yarnpkg.com/@nozbe/with-observables/-/with-observables-1.4.0.tgz#38d91186c932d431b767302f9f31214335912c6a"
integrity sha512-vzc0QiYcXK/GmflBGBXTs02ayL25e1l4Cr9aYgSuYCZVqpyMfep9xp89RygNbiibAfVLbgEUa7thxlm3jw8hFw==
dependencies:
hoist-non-react-statics "^3.3.2"
"@reach/router@^1.2.1": "@reach/router@^1.2.1":
version "1.3.3" version "1.3.3"
resolved "https://registry.yarnpkg.com/@reach/router/-/router-1.3.3.tgz#58162860dce6c9449d49be86b0561b5ef46d80db" resolved "https://registry.yarnpkg.com/@reach/router/-/router-1.3.3.tgz#58162860dce6c9449d49be86b0561b5ef46d80db"
@ -6361,11 +6389,6 @@ concat-stream@^2.0.0:
readable-stream "^3.0.2" readable-stream "^3.0.2"
typedarray "^0.0.6" typedarray "^0.0.6"
confusing-browser-globals@^1.0.9:
version "1.0.9"
resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz#72bc13b483c0276801681871d4898516f8f54fdd"
integrity sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==
connect@^3.6.5: connect@^3.6.5:
version "3.7.0" version "3.7.0"
resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8"
@ -7477,24 +7500,6 @@ escodegen@^2.0.0:
optionalDependencies: optionalDependencies:
source-map "~0.6.1" source-map "~0.6.1"
eslint-config-airbnb-base@^14.1.0:
version "14.1.0"
resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.1.0.tgz#2ba4592dd6843258221d9bff2b6831bd77c874e4"
integrity sha512-+XCcfGyCnbzOnktDVhwsCAx+9DmrzEmuwxyHUJpw+kqBVT744OUBrB09khgFKlK1lshVww6qXGsYPZpavoNjJw==
dependencies:
confusing-browser-globals "^1.0.9"
object.assign "^4.1.0"
object.entries "^1.1.1"
eslint-config-airbnb@^18.1.0:
version "18.1.0"
resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-18.1.0.tgz#724d7e93dadd2169492ff5363c5aaa779e01257d"
integrity sha512-kZFuQC/MPnH7KJp6v95xsLBf63G/w7YqdPfQ0MUanxQ7zcKUNG8j+sSY860g3NwCBOa62apw16J6pRN+AOgXzw==
dependencies:
eslint-config-airbnb-base "^14.1.0"
object.assign "^4.1.0"
object.entries "^1.1.1"
eslint-config-prettier@^8.3.0: eslint-config-prettier@^8.3.0:
version "8.3.0" version "8.3.0"
resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a" resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.3.0.tgz#f7471b20b6fe8a9a9254cc684454202886a2dd7a"
@ -8147,7 +8152,7 @@ fbjs-css-vars@^1.0.0:
resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8" resolved "https://registry.yarnpkg.com/fbjs-css-vars/-/fbjs-css-vars-1.0.2.tgz#216551136ae02fe255932c3ec8775f18e2c078b8"
integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ== integrity sha512-b2XGFAFdWZWg0phtAWLHCk836A1Xann+I+Dgd3Gk64MHKZO44FfoD1KxyvbSh0qZsIoXQGGlVztIY+oitJPpRQ==
fbjs@1.0.0, fbjs@^1.0.0: fbjs@1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-1.0.0.tgz#52c215e0883a3c86af2a7a776ed51525ae8e0a5a" resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-1.0.0.tgz#52c215e0883a3c86af2a7a776ed51525ae8e0a5a"
integrity sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA== integrity sha512-MUgcMEJaFhCaF1QtWGnmq9ZDRAzECTCRAF7O6UZIlAlkTs1SasiX9aP0Iw7wfD2mJ7wDTNfg2w7u5fSCwJk1OA==
@ -11212,10 +11217,10 @@ logkitty@^0.7.1:
dayjs "^1.8.15" dayjs "^1.8.15"
yargs "^15.1.0" yargs "^15.1.0"
"lokijs@npm:@nozbe/lokijs@1.5.10-wmelon0": "lokijs@npm:@nozbe/lokijs@1.5.12-wmelon2":
version "1.5.10-wmelon0" version "1.5.12-wmelon2"
resolved "https://registry.yarnpkg.com/@nozbe/lokijs/-/lokijs-1.5.10-wmelon0.tgz#dcad682083b85c238d14cdcd1f016125fff54336" resolved "https://registry.yarnpkg.com/@nozbe/lokijs/-/lokijs-1.5.12-wmelon2.tgz#31bc7b2d0c62edc1ccabd50ba795635d40e3e8c9"
integrity sha512-GSLyRUTxCPwWLLKxMxA8/Pujm2xAgPGSehze9ICHZDG9yyMMfuWYae+qY+fQctgA1HuKiwoRUEvrrKBCQj9jzA== integrity sha512-/YkZghPWKmyXgVpZ2MaIe3y/t/IYm/wQxXyEoi0G8JrjTrO9tlrAs2uiHUhbdY/2ZSPMLKbw1q9EqXZxA8ZqnQ==
long@~3: long@~3:
version "3.2.0" version "3.2.0"
@ -11904,6 +11909,11 @@ mocha@9.0.1:
yargs-parser "20.2.4" yargs-parser "20.2.4"
yargs-unparser "2.0.0" yargs-unparser "2.0.0"
mockdate@^3.0.2:
version "3.0.5"
resolved "https://registry.yarnpkg.com/mockdate/-/mockdate-3.0.5.tgz#789be686deb3149e7df2b663d2bc4392bc3284fb"
integrity sha512-iniQP4rj1FhBdBYS/+eQv7j1tadJ9lJtdzgOpvsOHng/GbcDh2Fhdeq+ZRldrPYdXvCyfFUmFeEwEGXZB5I/AQ==
moment@2.29.1, moment@^2.19.3, moment@^2.24.0: moment@2.29.1, moment@^2.19.3, moment@^2.24.0:
version "2.29.1" version "2.29.1"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3"
@ -12289,7 +12299,7 @@ object.assign@^4.1.2:
has-symbols "^1.0.1" has-symbols "^1.0.1"
object-keys "^1.1.1" object-keys "^1.1.1"
object.entries@^1.1.0, object.entries@^1.1.1: object.entries@^1.1.0:
version "1.1.2" version "1.1.2"
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.2.tgz#bc73f00acb6b6bb16c203434b10f9a7e797d3add" resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.2.tgz#bc73f00acb6b6bb16c203434b10f9a7e797d3add"
integrity sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA== integrity sha512-BQdB9qKmb/HyNdMNWVr7O3+z5MUIx3aiegEIJqjMBbBf0YT9RRxTJSim4mzFqtyr7PDAHigq0N9dO0m0tRakQA==
@ -13394,11 +13404,6 @@ queue-microtask@^1.2.2:
resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243"
integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==
rambdax@2.15.0:
version "2.15.0"
resolved "https://registry.yarnpkg.com/rambdax/-/rambdax-2.15.0.tgz#34fb481cea1a88e64a25e3a25e34a258fa18ca12"
integrity sha512-9ScXRMAcLaiist63yYDeDTRSIbL9DFY5yaIkoWyodaHS94PUL1ECQxQkxPP+h76oXG6bLo9b/ML+yvIRd78qeg==
ramda@^0.21.0: ramda@^0.21.0:
version "0.21.0" version "0.21.0"
resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35" resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.21.0.tgz#a001abedb3ff61077d4ff1d577d44de77e8d0a35"
@ -13674,8 +13679,8 @@ react-native-gesture-handler@^1.10.3:
prop-types "^15.7.2" prop-types "^15.7.2"
react-native-image-crop-picker@RocketChat/react-native-image-crop-picker: react-native-image-crop-picker@RocketChat/react-native-image-crop-picker:
version "0.31.1" version "0.36.3"
resolved "https://codeload.github.com/RocketChat/react-native-image-crop-picker/tar.gz/db1040b57e8536bd64db699897361167009b359c" resolved "https://codeload.github.com/RocketChat/react-native-image-crop-picker/tar.gz/f347776247afb5cbd1400dde215689d7ca8fd6f2"
react-native-image-progress@^1.1.1: react-native-image-progress@^1.1.1:
version "1.1.1" version "1.1.1"
@ -13782,12 +13787,15 @@ react-native-prompt-android@^1.1.0:
resolved "https://registry.yarnpkg.com/react-native-prompt-android/-/react-native-prompt-android-1.1.0.tgz#3c5168029075cb9f72549fd5f92403372fb234e9" resolved "https://registry.yarnpkg.com/react-native-prompt-android/-/react-native-prompt-android-1.1.0.tgz#3c5168029075cb9f72549fd5f92403372fb234e9"
integrity sha512-4JoyEaT2ZnK9IH+tDFpbTiQBgva8UIFGQf4/Uw/tnEVWBERlVlzcs5B82T9BkeEhEqXhp89JaiSBnLWj30lciw== integrity sha512-4JoyEaT2ZnK9IH+tDFpbTiQBgva8UIFGQf4/Uw/tnEVWBERlVlzcs5B82T9BkeEhEqXhp89JaiSBnLWj30lciw==
react-native-reanimated@1.9.0: react-native-reanimated@2.2.2:
version "1.9.0" version "2.2.2"
resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-1.9.0.tgz#38676c99dd585504fdc7331efb45e5f48ec7339a" resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.2.2.tgz#8bc81c7ee93d599991507bb826050a5eeee1e7f2"
integrity sha512-Aj+spgIHRiVv7ezGADxnSH1EoKrQRD2+XaSiGY0MiB/pvRNNrZPSJ+3NVpvLwWf9lZMOP7dwqqyJIzoZgBDt8w== integrity sha512-Lfv4ogbNLU9x3DqhXUFza9pnzyTvPrw5xGC1wWA6aGXqZgyaikNLgC5dNWzxVbfEwRdOuLPFsai3LAcIM92TCg==
dependencies: dependencies:
fbjs "^1.0.0" "@babel/plugin-transform-object-assign" "^7.10.4"
fbjs "^3.0.0"
mockdate "^3.0.2"
string-hash-64 "^1.0.3"
react-native-redash@^12.0.3: react-native-redash@^12.0.3:
version "12.6.1" version "12.6.1"
@ -14599,18 +14607,6 @@ run-queue@^1.0.0, run-queue@^1.0.3:
dependencies: dependencies:
aproba "^1.1.1" aproba "^1.1.1"
rxjs-compat@^6.3.2:
version "6.5.5"
resolved "https://registry.yarnpkg.com/rxjs-compat/-/rxjs-compat-6.5.5.tgz#073c40510f29c45a2a5fc02dde87f8c3ad75f2c2"
integrity sha512-F42sssVbUyWH4vJswEo6m+Eh02xHv3q93n8S7nUJO58R7sbc3CvJIOts605zdaBhWa1xMB9aVSyqPqhQ5q3eXg==
rxjs@^6.2.2, rxjs@^6.5.3:
version "6.5.5"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec"
integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==
dependencies:
tslib "^1.9.0"
rxjs@^6.4.0, rxjs@^6.6.7: rxjs@^6.4.0, rxjs@^6.6.7:
version "6.6.7" version "6.6.7"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
@ -14618,6 +14614,13 @@ rxjs@^6.4.0, rxjs@^6.6.7:
dependencies: dependencies:
tslib "^1.9.0" tslib "^1.9.0"
rxjs@^6.5.3:
version "6.5.5"
resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.5.5.tgz#c5c884e3094c8cfee31bf27eb87e54ccfc87f9ec"
integrity sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==
dependencies:
tslib "^1.9.0"
safe-buffer@5.1.1: safe-buffer@5.1.1:
version "5.1.1" version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
@ -15337,6 +15340,11 @@ string-argv@0.3.1:
resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da" resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.3.1.tgz#95e2fbec0427ae19184935f816d74aaa4c5c19da"
integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg== integrity sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==
string-hash-64@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/string-hash-64/-/string-hash-64-1.0.3.tgz#0deb56df58678640db5c479ccbbb597aaa0de322"
integrity sha512-D5OKWKvDhyVWWn2x5Y9b+37NUllks34q1dCDhk/vYcso9fmhs+Tl3KR/gE4v5UNj2UA35cnX4KdVVGkG1deKqw==
string-length@^4.0.1: string-length@^4.0.1:
version "4.0.2" version "4.0.2"
resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a"