chore: Merge 4.45.0 into master (#5482)
This commit is contained in:
commit
233b858070
|
@ -147,7 +147,7 @@ android {
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode VERSIONCODE as Integer
|
versionCode VERSIONCODE as Integer
|
||||||
versionName "4.44.2"
|
versionName "4.45.0"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
if (!isFoss) {
|
if (!isFoss) {
|
||||||
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
|
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
|
||||||
|
@ -380,6 +380,7 @@ dependencies {
|
||||||
androidTestImplementation('com.wix:detox:+')
|
androidTestImplementation('com.wix:detox:+')
|
||||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||||
implementation 'com.facebook.soloader:soloader:0.10.4'
|
implementation 'com.facebook.soloader:soloader:0.10.4'
|
||||||
|
implementation 'com.facebook.fresco:animated-gif:2.5.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isNewArchitectureEnabled()) {
|
if (isNewArchitectureEnabled()) {
|
||||||
|
|
|
@ -36,6 +36,7 @@ const IncomingCallHeader = React.memo(
|
||||||
({ uid, callId, avatar, roomName }: { callId: string; avatar: string; uid: string; roomName: string }) => {
|
({ uid, callId, avatar, roomName }: { callId: string; avatar: string; uid: string; roomName: string }) => {
|
||||||
const [mic, setMic] = useState(true);
|
const [mic, setMic] = useState(true);
|
||||||
const [cam, setCam] = useState(false);
|
const [cam, setCam] = useState(false);
|
||||||
|
const [audio, setAudio] = useState(true);
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
|
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
|
||||||
const styles = useStyle();
|
const styles = useStyle();
|
||||||
|
@ -64,12 +65,20 @@ const IncomingCallHeader = React.memo(
|
||||||
direct={true}
|
direct={true}
|
||||||
/>
|
/>
|
||||||
<View style={styles.row}>
|
<View style={styles.row}>
|
||||||
<Touchable hitSlop={BUTTON_HIT_SLOP} onPress={hideNotification} style={styles.closeButton}>
|
<Touchable
|
||||||
|
hitSlop={BUTTON_HIT_SLOP}
|
||||||
|
onPress={() => {
|
||||||
|
setAudio(!audio);
|
||||||
|
hideNotification();
|
||||||
|
}}
|
||||||
|
style={styles.closeButton}
|
||||||
|
>
|
||||||
<CustomIcon name='close' size={20} color={colors.gray300} />
|
<CustomIcon name='close' size={20} color={colors.gray300} />
|
||||||
</Touchable>
|
</Touchable>
|
||||||
<Touchable
|
<Touchable
|
||||||
hitSlop={BUTTON_HIT_SLOP}
|
hitSlop={BUTTON_HIT_SLOP}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
|
setAudio(!audio);
|
||||||
hideNotification();
|
hideNotification();
|
||||||
dispatch(cancelCall({ callId }));
|
dispatch(cancelCall({ callId }));
|
||||||
}}
|
}}
|
||||||
|
@ -80,6 +89,7 @@ const IncomingCallHeader = React.memo(
|
||||||
<Touchable
|
<Touchable
|
||||||
hitSlop={BUTTON_HIT_SLOP}
|
hitSlop={BUTTON_HIT_SLOP}
|
||||||
onPress={() => {
|
onPress={() => {
|
||||||
|
setAudio(!audio);
|
||||||
hideNotification();
|
hideNotification();
|
||||||
dispatch(acceptCall({ callId }));
|
dispatch(acceptCall({ callId }));
|
||||||
}}
|
}}
|
||||||
|
@ -88,7 +98,7 @@ const IncomingCallHeader = React.memo(
|
||||||
<Text style={styles.buttonText}>{i18n.t('accept')}</Text>
|
<Text style={styles.buttonText}>{i18n.t('accept')}</Text>
|
||||||
</Touchable>
|
</Touchable>
|
||||||
</View>
|
</View>
|
||||||
<Ringer ringer={ERingerSounds.RINGTONE} />
|
{audio ? <Ringer ringer={ERingerSounds.RINGTONE} /> : null}
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { Audio } from 'expo-av';
|
import { Audio } from 'expo-av';
|
||||||
import React, { useEffect, useRef } from 'react';
|
import React, { useEffect, useRef } from 'react';
|
||||||
import { View } from 'react-native';
|
|
||||||
|
|
||||||
export enum ERingerSounds {
|
export enum ERingerSounds {
|
||||||
DIALTONE = 'dialtone',
|
DIALTONE = 'dialtone',
|
||||||
|
@ -8,34 +7,28 @@ export enum ERingerSounds {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Ringer = React.memo(({ ringer }: { ringer: ERingerSounds }) => {
|
const Ringer = React.memo(({ ringer }: { ringer: ERingerSounds }) => {
|
||||||
const sound = useRef<Audio.Sound | null>(null);
|
const sound = useRef(new Audio.Sound());
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
(async () => {
|
const loadAndPlay = async () => {
|
||||||
let expo = null;
|
try {
|
||||||
switch (ringer) {
|
const soundFile = ringer === ERingerSounds.DIALTONE ? require(`./dialtone.mp3`) : require(`./ringtone.mp3`);
|
||||||
case ERingerSounds.DIALTONE:
|
await sound.current.loadAsync(soundFile);
|
||||||
expo = await Audio.Sound.createAsync(require(`./dialtone.mp3`));
|
await sound.current.playAsync();
|
||||||
break;
|
await sound.current.setIsLoopingAsync(true);
|
||||||
case ERingerSounds.RINGTONE:
|
} catch (error) {
|
||||||
expo = await Audio.Sound.createAsync(require(`./ringtone.mp3`));
|
console.error('Error loading sound:', error);
|
||||||
break;
|
|
||||||
default:
|
|
||||||
expo = await Audio.Sound.createAsync(require(`./dialtone.mp3`));
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
sound.current = expo.sound;
|
};
|
||||||
await sound.current.playAsync();
|
|
||||||
await sound.current.setIsLoopingAsync(true);
|
loadAndPlay();
|
||||||
})();
|
|
||||||
|
return () => {
|
||||||
|
sound.current?.unloadAsync();
|
||||||
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => () => stopSound(), []);
|
return null;
|
||||||
|
|
||||||
const stopSound = () => {
|
|
||||||
sound?.current?.unloadAsync();
|
|
||||||
};
|
|
||||||
|
|
||||||
return <View />;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Ringer;
|
export default Ringer;
|
||||||
|
|
|
@ -20,6 +20,7 @@ import { CommandsEndpoints } from './commands';
|
||||||
import { PushTokenEndpoints } from './pushToken';
|
import { PushTokenEndpoints } from './pushToken';
|
||||||
import { DirectoryEndpoint } from './directory';
|
import { DirectoryEndpoint } from './directory';
|
||||||
import { AutoTranslateEndpoints } from './autotranslate';
|
import { AutoTranslateEndpoints } from './autotranslate';
|
||||||
|
import { ModerationEndpoints } from './moderation';
|
||||||
|
|
||||||
export type Endpoints = ChannelsEndpoints &
|
export type Endpoints = ChannelsEndpoints &
|
||||||
ChatEndpoints &
|
ChatEndpoints &
|
||||||
|
@ -42,4 +43,5 @@ export type Endpoints = ChannelsEndpoints &
|
||||||
CommandsEndpoints &
|
CommandsEndpoints &
|
||||||
PushTokenEndpoints &
|
PushTokenEndpoints &
|
||||||
DirectoryEndpoint &
|
DirectoryEndpoint &
|
||||||
AutoTranslateEndpoints;
|
AutoTranslateEndpoints &
|
||||||
|
ModerationEndpoints;
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
export type ModerationEndpoints = {
|
||||||
|
'moderation.reportUser': {
|
||||||
|
POST: (params: { userId: string; description: string }) => void;
|
||||||
|
};
|
||||||
|
};
|
|
@ -44,7 +44,6 @@
|
||||||
"Avatar_Url": "عنوان ويب الصورة الرمزية",
|
"Avatar_Url": "عنوان ويب الصورة الرمزية",
|
||||||
"Away": "غير متواجد",
|
"Away": "غير متواجد",
|
||||||
"Black": "أسود",
|
"Black": "أسود",
|
||||||
"Block_user": "حظر المستخدم",
|
|
||||||
"Browser": "المتصفح",
|
"Browser": "المتصفح",
|
||||||
"Busy": "مشغول",
|
"Busy": "مشغول",
|
||||||
"Cancel_editing": "إلغاء التعديل",
|
"Cancel_editing": "إلغاء التعديل",
|
||||||
|
@ -372,7 +371,6 @@
|
||||||
"Two_Factor_Authentication": "المصادقة الثنائية",
|
"Two_Factor_Authentication": "المصادقة الثنائية",
|
||||||
"unarchive": "إلغاء الأرشفة",
|
"unarchive": "إلغاء الأرشفة",
|
||||||
"UNARCHIVE": "إلغاء الأرشفة",
|
"UNARCHIVE": "إلغاء الأرشفة",
|
||||||
"Unblock_user": "إلغاء حظر عن مستخدم",
|
|
||||||
"Unfollowed_thread": "موضوع غير متابع",
|
"Unfollowed_thread": "موضوع غير متابع",
|
||||||
"Unmute": "إلغاء كتم",
|
"Unmute": "إلغاء كتم",
|
||||||
"unmuted": "إلغاء كتم",
|
"unmuted": "إلغاء كتم",
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"Avatar_Url": "অবতার URL",
|
"Avatar_Url": "অবতার URL",
|
||||||
"Away": "দূরে",
|
"Away": "দূরে",
|
||||||
"Black": "কালো",
|
"Black": "কালো",
|
||||||
"Block_user": "ব্যবহারকারী ব্লক করুন",
|
|
||||||
"Browser": "ব্রাউজার",
|
"Browser": "ব্রাউজার",
|
||||||
"Busy": "ব্যস্ত",
|
"Busy": "ব্যস্ত",
|
||||||
"Cancel_editing": "সম্পাদনা বাতিল করুন",
|
"Cancel_editing": "সম্পাদনা বাতিল করুন",
|
||||||
|
@ -405,7 +404,6 @@
|
||||||
"Two_Factor_Authentication": "দুটি ধারণামূলক প্রমাণীকরণ",
|
"Two_Factor_Authentication": "দুটি ধারণামূলক প্রমাণীকরণ",
|
||||||
"unarchive": "আনআরকাইভ",
|
"unarchive": "আনআরকাইভ",
|
||||||
"UNARCHIVE": "আনআরকাইভ",
|
"UNARCHIVE": "আনআরকাইভ",
|
||||||
"Unblock_user": "ব্যবহারকারী আনব্লক করুন",
|
|
||||||
"Unfollowed_thread": "থ্রেড অনফলোয়েড",
|
"Unfollowed_thread": "থ্রেড অনফলোয়েড",
|
||||||
"Unmute": "আনমিউট",
|
"Unmute": "আনমিউট",
|
||||||
"unmuted": "আনমিউটেড",
|
"unmuted": "আনমিউটেড",
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"Avatar_Url": "Avatar-URL",
|
"Avatar_Url": "Avatar-URL",
|
||||||
"Away": "Abwesend",
|
"Away": "Abwesend",
|
||||||
"Black": "Schwarz",
|
"Black": "Schwarz",
|
||||||
"Block_user": "Benutzer blockieren",
|
|
||||||
"Browser": "Browser",
|
"Browser": "Browser",
|
||||||
"Busy": "Beschäftigt",
|
"Busy": "Beschäftigt",
|
||||||
"Cancel_editing": "Bearbeitung abbrechen",
|
"Cancel_editing": "Bearbeitung abbrechen",
|
||||||
|
@ -406,7 +405,6 @@
|
||||||
"Two_Factor_Authentication": "Zwei-Faktor-Authentifizierung",
|
"Two_Factor_Authentication": "Zwei-Faktor-Authentifizierung",
|
||||||
"unarchive": "wiederherstellen",
|
"unarchive": "wiederherstellen",
|
||||||
"UNARCHIVE": "WIEDERHERSTELLEN",
|
"UNARCHIVE": "WIEDERHERSTELLEN",
|
||||||
"Unblock_user": "Benutzer entsperren",
|
|
||||||
"Unfollowed_thread": "Thread nicht mehr folgen",
|
"Unfollowed_thread": "Thread nicht mehr folgen",
|
||||||
"Unmute": "Stummschaltung aufheben",
|
"Unmute": "Stummschaltung aufheben",
|
||||||
"unmuted": "Stummschaltung aufgehoben",
|
"unmuted": "Stummschaltung aufgehoben",
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"Avatar_Url": "Avatar URL",
|
"Avatar_Url": "Avatar URL",
|
||||||
"Away": "Away",
|
"Away": "Away",
|
||||||
"Black": "Black",
|
"Black": "Black",
|
||||||
"Block_user": "Block user",
|
|
||||||
"Browser": "Browser",
|
"Browser": "Browser",
|
||||||
"Busy": "Busy",
|
"Busy": "Busy",
|
||||||
"Cancel_editing": "Cancel editing",
|
"Cancel_editing": "Cancel editing",
|
||||||
|
@ -407,7 +406,6 @@
|
||||||
"Two_Factor_Authentication": "Two-factor authentication",
|
"Two_Factor_Authentication": "Two-factor authentication",
|
||||||
"unarchive": "unarchive",
|
"unarchive": "unarchive",
|
||||||
"UNARCHIVE": "UNARCHIVE",
|
"UNARCHIVE": "UNARCHIVE",
|
||||||
"Unblock_user": "Unblock user",
|
|
||||||
"Unfollowed_thread": "Unfollowed thread",
|
"Unfollowed_thread": "Unfollowed thread",
|
||||||
"Unmute": "Unmute",
|
"Unmute": "Unmute",
|
||||||
"unmuted": "unmuted",
|
"unmuted": "unmuted",
|
||||||
|
@ -762,6 +760,11 @@
|
||||||
"Enable_writing_in_room": "Enable writing in room",
|
"Enable_writing_in_room": "Enable writing in room",
|
||||||
"Disable_writing_in_room": "Disable writing in room",
|
"Disable_writing_in_room": "Disable writing in room",
|
||||||
"Pinned_a_message": "Pinned a message:",
|
"Pinned_a_message": "Pinned a message:",
|
||||||
|
"Unblock": "Unblock",
|
||||||
|
"Block": "Block",
|
||||||
|
"Report_user": "Report user",
|
||||||
|
"Report_sent_successfully": "Report sent successfully",
|
||||||
|
"Why_do_you_want_to_report": "Why do you want to report?",
|
||||||
"You_dont_have_permission_to_perform_this_action": "You don’t have permission to perform this action. Check with a workspace administrator.",
|
"You_dont_have_permission_to_perform_this_action": "You don’t have permission to perform this action. Check with a workspace administrator.",
|
||||||
"Jump_to_message": "Jump to message",
|
"Jump_to_message": "Jump to message",
|
||||||
"Missed_call": "Missed call"
|
"Missed_call": "Missed call"
|
||||||
|
|
|
@ -38,7 +38,6 @@
|
||||||
"Avatar_Url": "URL del Avatar",
|
"Avatar_Url": "URL del Avatar",
|
||||||
"Away": "Ausente",
|
"Away": "Ausente",
|
||||||
"Black": "Negro",
|
"Black": "Negro",
|
||||||
"Block_user": "Bloquear usuario",
|
|
||||||
"Busy": "Ocupado",
|
"Busy": "Ocupado",
|
||||||
"Cancel_editing": "Cancelar edición",
|
"Cancel_editing": "Cancelar edición",
|
||||||
"Cancel_recording": "Cancelar grabación",
|
"Cancel_recording": "Cancelar grabación",
|
||||||
|
@ -239,7 +238,6 @@
|
||||||
"Two_Factor_Authentication": "Autenticación de doble factor",
|
"Two_Factor_Authentication": "Autenticación de doble factor",
|
||||||
"unarchive": "desarchivar",
|
"unarchive": "desarchivar",
|
||||||
"UNARCHIVE": "DESARCHIVAR",
|
"UNARCHIVE": "DESARCHIVAR",
|
||||||
"Unblock_user": "Desbloquear usuario",
|
|
||||||
"Unfollowed_thread": "Dejar de seguir el hilo",
|
"Unfollowed_thread": "Dejar de seguir el hilo",
|
||||||
"Unmute": "Desmutear",
|
"Unmute": "Desmutear",
|
||||||
"unmuted": "Desmuteado",
|
"unmuted": "Desmuteado",
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"Avatar_Url": "Avatarin URL-osoite",
|
"Avatar_Url": "Avatarin URL-osoite",
|
||||||
"Away": "Poissa",
|
"Away": "Poissa",
|
||||||
"Black": "Musta",
|
"Black": "Musta",
|
||||||
"Block_user": "Estä käyttäjä",
|
|
||||||
"Browser": "Selain",
|
"Browser": "Selain",
|
||||||
"Busy": "Varattu",
|
"Busy": "Varattu",
|
||||||
"Cancel_editing": "Peruuta muokkaus",
|
"Cancel_editing": "Peruuta muokkaus",
|
||||||
|
@ -406,7 +405,6 @@
|
||||||
"Two_Factor_Authentication": "Kaksivaiheinen tunnistautuminen",
|
"Two_Factor_Authentication": "Kaksivaiheinen tunnistautuminen",
|
||||||
"unarchive": "palauta arkistosta",
|
"unarchive": "palauta arkistosta",
|
||||||
"UNARCHIVE": "PALAUTA ARKISTOSTA",
|
"UNARCHIVE": "PALAUTA ARKISTOSTA",
|
||||||
"Unblock_user": "Poista käyttäjän esto",
|
|
||||||
"Unfollowed_thread": "Lopetettiin ketjun seuraaminen",
|
"Unfollowed_thread": "Lopetettiin ketjun seuraaminen",
|
||||||
"Unmute": "Mykistys poistettu",
|
"Unmute": "Mykistys poistettu",
|
||||||
"unmuted": "poisti mykistyksen",
|
"unmuted": "poisti mykistyksen",
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
"Avatar_Url": "URL de l'avatar",
|
"Avatar_Url": "URL de l'avatar",
|
||||||
"Away": "Absent",
|
"Away": "Absent",
|
||||||
"Black": "Noir",
|
"Black": "Noir",
|
||||||
"Block_user": "Bloquer l'utilisateur",
|
|
||||||
"Browser": "Navigateur",
|
"Browser": "Navigateur",
|
||||||
"Busy": "Occupé",
|
"Busy": "Occupé",
|
||||||
"Cancel_editing": "Annuler la modification",
|
"Cancel_editing": "Annuler la modification",
|
||||||
|
@ -381,7 +380,6 @@
|
||||||
"Two_Factor_Authentication": "Authentification à deux facteurs",
|
"Two_Factor_Authentication": "Authentification à deux facteurs",
|
||||||
"unarchive": "désarchiver",
|
"unarchive": "désarchiver",
|
||||||
"UNARCHIVE": "DÉSARCHIVER",
|
"UNARCHIVE": "DÉSARCHIVER",
|
||||||
"Unblock_user": "Débloquer l'utilisateur",
|
|
||||||
"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",
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"Avatar_Url": "अवतार URL",
|
"Avatar_Url": "अवतार URL",
|
||||||
"Away": "दूर",
|
"Away": "दूर",
|
||||||
"Black": "काला",
|
"Black": "काला",
|
||||||
"Block_user": "उपयोगकर्ता को ब्लॉक करें",
|
|
||||||
"Browser": "ब्राउज़र",
|
"Browser": "ब्राउज़र",
|
||||||
"Busy": "व्यस्त",
|
"Busy": "व्यस्त",
|
||||||
"Cancel_editing": "संपादन रद्द करें",
|
"Cancel_editing": "संपादन रद्द करें",
|
||||||
|
@ -405,7 +404,6 @@
|
||||||
"Two_Factor_Authentication": "दो-क्रमिक प्रमाणीकरण",
|
"Two_Factor_Authentication": "दो-क्रमिक प्रमाणीकरण",
|
||||||
"unarchive": "अनारकाइव",
|
"unarchive": "अनारकाइव",
|
||||||
"UNARCHIVE": "अनारकाइव करें",
|
"UNARCHIVE": "अनारकाइव करें",
|
||||||
"Unblock_user": "उपयोगकर्ता को अनब्लॉक करें",
|
|
||||||
"Unfollowed_thread": "थ्रेड का अनुसरण नहीं किया गया",
|
"Unfollowed_thread": "थ्रेड का अनुसरण नहीं किया गया",
|
||||||
"Unmute": "आवाज़ हटाएं",
|
"Unmute": "आवाज़ हटाएं",
|
||||||
"unmuted": "आवाज़ हटाई गई",
|
"unmuted": "आवाज़ हटाई गई",
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"Avatar_Url": "Avatar URL",
|
"Avatar_Url": "Avatar URL",
|
||||||
"Away": "Távol",
|
"Away": "Távol",
|
||||||
"Black": "Fekete",
|
"Black": "Fekete",
|
||||||
"Block_user": "Felhasználó tiltása",
|
|
||||||
"Browser": "Böngésző",
|
"Browser": "Böngésző",
|
||||||
"Busy": "Elfoglalt",
|
"Busy": "Elfoglalt",
|
||||||
"Cancel_editing": "Szerkesztés megszakítás",
|
"Cancel_editing": "Szerkesztés megszakítás",
|
||||||
|
@ -406,7 +405,6 @@
|
||||||
"Two_Factor_Authentication": "Kétfaktoros hitelesítés",
|
"Two_Factor_Authentication": "Kétfaktoros hitelesítés",
|
||||||
"unarchive": "Archiválás megszüntetés",
|
"unarchive": "Archiválás megszüntetés",
|
||||||
"UNARCHIVE": "ARCHIVÁLÁS MEGSZÜNTETÉS",
|
"UNARCHIVE": "ARCHIVÁLÁS MEGSZÜNTETÉS",
|
||||||
"Unblock_user": "Felhasználó tiltás feloldása",
|
|
||||||
"Unfollowed_thread": "Nem követett szál",
|
"Unfollowed_thread": "Nem követett szál",
|
||||||
"Unmute": "Némítás megszüntetése",
|
"Unmute": "Némítás megszüntetése",
|
||||||
"unmuted": "Némítás megszüntetve",
|
"unmuted": "Némítás megszüntetve",
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"Avatar_Url": "URL avatar",
|
"Avatar_Url": "URL avatar",
|
||||||
"Away": "Assente",
|
"Away": "Assente",
|
||||||
"Black": "Nero",
|
"Black": "Nero",
|
||||||
"Block_user": "Blocca utente",
|
|
||||||
"Browser": "Browser",
|
"Browser": "Browser",
|
||||||
"Busy": "Occupato",
|
"Busy": "Occupato",
|
||||||
"Cancel_editing": "Annulla modifica",
|
"Cancel_editing": "Annulla modifica",
|
||||||
|
@ -386,7 +385,6 @@
|
||||||
"Two_Factor_Authentication": "Autenticazione a due fattori",
|
"Two_Factor_Authentication": "Autenticazione a due fattori",
|
||||||
"unarchive": "rimuovi dall'archivio",
|
"unarchive": "rimuovi dall'archivio",
|
||||||
"UNARCHIVE": "RIMUOVI DALL'ARCHIVIO",
|
"UNARCHIVE": "RIMUOVI DALL'ARCHIVIO",
|
||||||
"Unblock_user": "Sblocca utente",
|
|
||||||
"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",
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
"Avatar_Url": "アバターURL",
|
"Avatar_Url": "アバターURL",
|
||||||
"Away": "退出中",
|
"Away": "退出中",
|
||||||
"Black": "ブラック",
|
"Black": "ブラック",
|
||||||
"Block_user": "ブロックしたユーザー",
|
|
||||||
"Browser": "ブラウザ",
|
"Browser": "ブラウザ",
|
||||||
"Busy": "取り込み中",
|
"Busy": "取り込み中",
|
||||||
"Cancel_editing": "編集をキャンセル",
|
"Cancel_editing": "編集をキャンセル",
|
||||||
|
@ -334,7 +333,6 @@
|
||||||
"Two_Factor_Authentication": "2段階認証",
|
"Two_Factor_Authentication": "2段階認証",
|
||||||
"unarchive": "アーカイブ解除",
|
"unarchive": "アーカイブ解除",
|
||||||
"UNARCHIVE": "アーカイブ解除",
|
"UNARCHIVE": "アーカイブ解除",
|
||||||
"Unblock_user": "ブロックを解除",
|
|
||||||
"Unfollowed_thread": "スレッド更新時に通知しない",
|
"Unfollowed_thread": "スレッド更新時に通知しない",
|
||||||
"Unmute": "ミュート解除",
|
"Unmute": "ミュート解除",
|
||||||
"unmuted": "ミュート解除しました",
|
"unmuted": "ミュート解除しました",
|
||||||
|
|
|
@ -45,7 +45,6 @@
|
||||||
"Avatar_Url": "Avatar-URL",
|
"Avatar_Url": "Avatar-URL",
|
||||||
"Away": "Afwezig",
|
"Away": "Afwezig",
|
||||||
"Black": "Zwart",
|
"Black": "Zwart",
|
||||||
"Block_user": "Blokkeer gebruiker",
|
|
||||||
"Browser": "Browser",
|
"Browser": "Browser",
|
||||||
"Busy": "Bezig",
|
"Busy": "Bezig",
|
||||||
"Cancel_editing": "Bewerken annuleren",
|
"Cancel_editing": "Bewerken annuleren",
|
||||||
|
@ -381,7 +380,6 @@
|
||||||
"Two_Factor_Authentication": "Twee-factor authenticatie",
|
"Two_Factor_Authentication": "Twee-factor authenticatie",
|
||||||
"unarchive": "dearchiveren",
|
"unarchive": "dearchiveren",
|
||||||
"UNARCHIVE": "DEARCHIVEREN",
|
"UNARCHIVE": "DEARCHIVEREN",
|
||||||
"Unblock_user": "Deblokkeer gebruiker",
|
|
||||||
"Unfollowed_thread": "Draad ontvolgd",
|
"Unfollowed_thread": "Draad ontvolgd",
|
||||||
"Unmute": "Dempen opheffen",
|
"Unmute": "Dempen opheffen",
|
||||||
"unmuted": "ongedempt",
|
"unmuted": "ongedempt",
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"Avatar_Url": "Avatar URL",
|
"Avatar_Url": "Avatar URL",
|
||||||
"Away": "Ausente",
|
"Away": "Ausente",
|
||||||
"Black": "Preto",
|
"Black": "Preto",
|
||||||
"Block_user": "Bloquear usuário",
|
|
||||||
"Browser": "Navegador",
|
"Browser": "Navegador",
|
||||||
"Busy": "Ocupado",
|
"Busy": "Ocupado",
|
||||||
"Cancel_editing": "Cancelar edição",
|
"Cancel_editing": "Cancelar edição",
|
||||||
|
@ -407,7 +406,6 @@
|
||||||
"Two_Factor_Authentication": "Autenticação de dois fatores",
|
"Two_Factor_Authentication": "Autenticação de dois fatores",
|
||||||
"unarchive": "desarquivar",
|
"unarchive": "desarquivar",
|
||||||
"UNARCHIVE": "DESARQUIVAR",
|
"UNARCHIVE": "DESARQUIVAR",
|
||||||
"Unblock_user": "Desbloquear usuário",
|
|
||||||
"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",
|
||||||
|
@ -761,6 +759,11 @@
|
||||||
"The_user_will_be_able_to_type_in_roomName": "O usuário poderá digitar em {{roomName}}",
|
"The_user_will_be_able_to_type_in_roomName": "O usuário poderá digitar em {{roomName}}",
|
||||||
"Enable_writing_in_room": "Permitir escrita na sala",
|
"Enable_writing_in_room": "Permitir escrita na sala",
|
||||||
"Disable_writing_in_room": "Desabilitar escrita na sala",
|
"Disable_writing_in_room": "Desabilitar escrita na sala",
|
||||||
|
"Unblock": "Desbloquear",
|
||||||
|
"Block": "Bloquear",
|
||||||
|
"Report_user": "Reportar usuário",
|
||||||
|
"Report_sent_successfully": "Reporte enviado com sucesso",
|
||||||
|
"Why_do_you_want_to_report": "Por que você deseja reportar?",
|
||||||
"Pinned_a_message": "Fixou uma mensagem:",
|
"Pinned_a_message": "Fixou uma mensagem:",
|
||||||
"You_dont_have_permission_to_perform_this_action": "Você não tem permissão para realizar esta ação. Verifique com um administrador do espaço de trabalho.",
|
"You_dont_have_permission_to_perform_this_action": "Você não tem permissão para realizar esta ação. Verifique com um administrador do espaço de trabalho.",
|
||||||
"Jump_to_message": "Ir para mensagem",
|
"Jump_to_message": "Ir para mensagem",
|
||||||
|
|
|
@ -44,7 +44,6 @@
|
||||||
"Avatar_Url": "URL do Avatar",
|
"Avatar_Url": "URL do Avatar",
|
||||||
"Away": "Ausente",
|
"Away": "Ausente",
|
||||||
"Black": "Preto",
|
"Black": "Preto",
|
||||||
"Block_user": "Bloquear utilizador",
|
|
||||||
"Browser": "Navegador",
|
"Browser": "Navegador",
|
||||||
"Busy": "Ocupado",
|
"Busy": "Ocupado",
|
||||||
"Cancel_editing": "Cancelar edição",
|
"Cancel_editing": "Cancelar edição",
|
||||||
|
@ -323,7 +322,6 @@
|
||||||
"Two_Factor_Authentication": "Autenticação 2FA",
|
"Two_Factor_Authentication": "Autenticação 2FA",
|
||||||
"unarchive": "desarquivar",
|
"unarchive": "desarquivar",
|
||||||
"UNARCHIVE": "DESARQUIVAR",
|
"UNARCHIVE": "DESARQUIVAR",
|
||||||
"Unblock_user": "Desbloquear utilizador",
|
|
||||||
"Unmute": "Retirar silêncio",
|
"Unmute": "Retirar silêncio",
|
||||||
"unmuted": "silêncio removido",
|
"unmuted": "silêncio removido",
|
||||||
"Unpin": "Desafixar",
|
"Unpin": "Desafixar",
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"Avatar_Url": "URL аватара",
|
"Avatar_Url": "URL аватара",
|
||||||
"Away": "Отошел",
|
"Away": "Отошел",
|
||||||
"Black": "Черный",
|
"Black": "Черный",
|
||||||
"Block_user": "Блокировать пользователя",
|
|
||||||
"Browser": "Браузер",
|
"Browser": "Браузер",
|
||||||
"Busy": "Занят",
|
"Busy": "Занят",
|
||||||
"Cancel_editing": "Отменить правку",
|
"Cancel_editing": "Отменить правку",
|
||||||
|
@ -392,7 +391,6 @@
|
||||||
"Two_Factor_Authentication": "Двухфакторная аутентификация",
|
"Two_Factor_Authentication": "Двухфакторная аутентификация",
|
||||||
"unarchive": "разархивировать",
|
"unarchive": "разархивировать",
|
||||||
"UNARCHIVE": "РАЗАРХИВИРОВАТЬ",
|
"UNARCHIVE": "РАЗАРХИВИРОВАТЬ",
|
||||||
"Unblock_user": "Разблокировать пользователя",
|
|
||||||
"Unfollowed_thread": "Не следить",
|
"Unfollowed_thread": "Не следить",
|
||||||
"Unmute": "Отменить заглушивание",
|
"Unmute": "Отменить заглушивание",
|
||||||
"unmuted": "Заглушивание отменено",
|
"unmuted": "Заглушивание отменено",
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"Avatar_Url": "Avatar URL",
|
"Avatar_Url": "Avatar URL",
|
||||||
"Away": "Odsoten",
|
"Away": "Odsoten",
|
||||||
"Black": "Črn",
|
"Black": "Črn",
|
||||||
"Block_user": "Blokiraj uporabnika",
|
|
||||||
"Browser": "Brskalnik",
|
"Browser": "Brskalnik",
|
||||||
"Busy": "Zaseden",
|
"Busy": "Zaseden",
|
||||||
"Cancel_editing": "Prekliči urejanje",
|
"Cancel_editing": "Prekliči urejanje",
|
||||||
|
@ -389,7 +388,6 @@
|
||||||
"Two_Factor_Authentication": "Dvofaktorska overjanje",
|
"Two_Factor_Authentication": "Dvofaktorska overjanje",
|
||||||
"unarchive": "Odpakirati",
|
"unarchive": "Odpakirati",
|
||||||
"UNARCHIVE": "ODPAKIRATI",
|
"UNARCHIVE": "ODPAKIRATI",
|
||||||
"Unblock_user": "Odblokirati uporabnika",
|
|
||||||
"Unfollowed_thread": "Nit, ki ji nihče ne sledi",
|
"Unfollowed_thread": "Nit, ki ji nihče ne sledi",
|
||||||
"Unmute": "Preklicati utišanje",
|
"Unmute": "Preklicati utišanje",
|
||||||
"unmuted": "preklicati utišanje",
|
"unmuted": "preklicati utišanje",
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"Avatar_Url": "URL till avatar",
|
"Avatar_Url": "URL till avatar",
|
||||||
"Away": "Borta",
|
"Away": "Borta",
|
||||||
"Black": "Svart",
|
"Black": "Svart",
|
||||||
"Block_user": "Blockera användare",
|
|
||||||
"Browser": "Webbläsare",
|
"Browser": "Webbläsare",
|
||||||
"Busy": "Upptagen",
|
"Busy": "Upptagen",
|
||||||
"Cancel_editing": "Avbryt redigering",
|
"Cancel_editing": "Avbryt redigering",
|
||||||
|
@ -406,7 +405,6 @@
|
||||||
"Two_Factor_Authentication": "Tvåfaktorsautentisering",
|
"Two_Factor_Authentication": "Tvåfaktorsautentisering",
|
||||||
"unarchive": "avarkivera",
|
"unarchive": "avarkivera",
|
||||||
"UNARCHIVE": "AVARKIVERA",
|
"UNARCHIVE": "AVARKIVERA",
|
||||||
"Unblock_user": "Avblockera användare",
|
|
||||||
"Unfollowed_thread": "Sluta följa tråd",
|
"Unfollowed_thread": "Sluta följa tråd",
|
||||||
"Unmute": "Slå på ljudet",
|
"Unmute": "Slå på ljudet",
|
||||||
"unmuted": "slog på ljudet",
|
"unmuted": "slog på ljudet",
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"Avatar_Url": "அவதார் URL",
|
"Avatar_Url": "அவதார் URL",
|
||||||
"Away": "விலகியிருக்கிறேன்",
|
"Away": "விலகியிருக்கிறேன்",
|
||||||
"Black": "கருப்பு",
|
"Black": "கருப்பு",
|
||||||
"Block_user": "பயனாளரை தடுக்கவும்",
|
|
||||||
"Browser": "உலாவி",
|
"Browser": "உலாவி",
|
||||||
"Busy": "தொலைநேரம்",
|
"Busy": "தொலைநேரம்",
|
||||||
"Cancel_editing": "திருத்தலை ரத்து செய்க",
|
"Cancel_editing": "திருத்தலை ரத்து செய்க",
|
||||||
|
@ -405,7 +404,6 @@
|
||||||
"Two_Factor_Authentication": "இரண்டு பரிமாறு அங்கீகாரம்",
|
"Two_Factor_Authentication": "இரண்டு பரிமாறு அங்கீகாரம்",
|
||||||
"unarchive": "அசைவு செய்",
|
"unarchive": "அசைவு செய்",
|
||||||
"UNARCHIVE": "அசைவு செய்",
|
"UNARCHIVE": "அசைவு செய்",
|
||||||
"Unblock_user": "பயனரை விடுவிக்கு",
|
|
||||||
"Unfollowed_thread": "பின்னாளிக்குப் பின்னாளிக்கப்பட்டுள்ளது",
|
"Unfollowed_thread": "பின்னாளிக்குப் பின்னாளிக்கப்பட்டுள்ளது",
|
||||||
"Unmute": "மூடாது",
|
"Unmute": "மூடாது",
|
||||||
"unmuted": "மூடப்படவில்லை",
|
"unmuted": "மூடப்படவில்லை",
|
||||||
|
|
|
@ -51,7 +51,6 @@
|
||||||
"Avatar_Url": "అవతార్ URL",
|
"Avatar_Url": "అవతార్ URL",
|
||||||
"Away": "దూరంగా",
|
"Away": "దూరంగా",
|
||||||
"Black": "నలుపు",
|
"Black": "నలుపు",
|
||||||
"Block_user": "వాడిని నిలిపించండి",
|
|
||||||
"Browser": "బ్రౌజర్",
|
"Browser": "బ్రౌజర్",
|
||||||
"Busy": "వ్యస్తంగా",
|
"Busy": "వ్యస్తంగా",
|
||||||
"Cancel_editing": "సవరించడానికి రద్దు చేయి",
|
"Cancel_editing": "సవరించడానికి రద్దు చేయి",
|
||||||
|
@ -405,7 +404,6 @@
|
||||||
"Two_Factor_Authentication": "రెండు అంశ ప్రామాణీకరణ",
|
"Two_Factor_Authentication": "రెండు అంశ ప్రామాణీకరణ",
|
||||||
"unarchive": "అనార్కైవ్",
|
"unarchive": "అనార్కైవ్",
|
||||||
"UNARCHIVE": "అనార్కైవ్",
|
"UNARCHIVE": "అనార్కైవ్",
|
||||||
"Unblock_user": "వాడుకరిని నిషేధించకోండి",
|
|
||||||
"Unfollowed_thread": "అన్ఫాలో థ్రెడ్",
|
"Unfollowed_thread": "అన్ఫాలో థ్రెడ్",
|
||||||
"Unmute": "ఆధ్వర్యపరచించండి",
|
"Unmute": "ఆధ్వర్యపరచించండి",
|
||||||
"unmuted": "ఆధ్వర్యపరచించబడింది",
|
"unmuted": "ఆధ్వర్యపరచించబడింది",
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
"Avatar_Url": "Profil fotoğrafı URL'si",
|
"Avatar_Url": "Profil fotoğrafı URL'si",
|
||||||
"Away": "Uzakta",
|
"Away": "Uzakta",
|
||||||
"Black": "Koyu",
|
"Black": "Koyu",
|
||||||
"Block_user": "Kullanıcıyı engelle",
|
|
||||||
"Browser": "Tarayıcı",
|
"Browser": "Tarayıcı",
|
||||||
"Busy": "Meşgul",
|
"Busy": "Meşgul",
|
||||||
"Cancel_editing": "Düzenlemeyi iptal et",
|
"Cancel_editing": "Düzenlemeyi iptal et",
|
||||||
|
@ -369,7 +368,6 @@
|
||||||
"Two_Factor_Authentication": "İki faktörlü Kimlik Doğrulama",
|
"Two_Factor_Authentication": "İki faktörlü Kimlik Doğrulama",
|
||||||
"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",
|
|
||||||
"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ı",
|
||||||
|
|
|
@ -43,7 +43,6 @@
|
||||||
"Avatar_Url": "头像地址",
|
"Avatar_Url": "头像地址",
|
||||||
"Away": "离开",
|
"Away": "离开",
|
||||||
"Black": "黑色",
|
"Black": "黑色",
|
||||||
"Block_user": "屏蔽此用户",
|
|
||||||
"Browser": "浏览器",
|
"Browser": "浏览器",
|
||||||
"Busy": "忙碌",
|
"Busy": "忙碌",
|
||||||
"Cancel_editing": "取消编辑",
|
"Cancel_editing": "取消编辑",
|
||||||
|
@ -365,7 +364,6 @@
|
||||||
"Two_Factor_Authentication": "双重认证",
|
"Two_Factor_Authentication": "双重认证",
|
||||||
"unarchive": "取消封存",
|
"unarchive": "取消封存",
|
||||||
"UNARCHIVE": "取消封存",
|
"UNARCHIVE": "取消封存",
|
||||||
"Unblock_user": "解除屏蔽",
|
|
||||||
"Unfollowed_thread": "取消追踪讨论",
|
"Unfollowed_thread": "取消追踪讨论",
|
||||||
"Unmute": "取消静音",
|
"Unmute": "取消静音",
|
||||||
"unmuted": "静音状态",
|
"unmuted": "静音状态",
|
||||||
|
|
|
@ -44,7 +44,6 @@
|
||||||
"Avatar_Url": "大頭貼地址",
|
"Avatar_Url": "大頭貼地址",
|
||||||
"Away": "離開",
|
"Away": "離開",
|
||||||
"Black": "黑色",
|
"Black": "黑色",
|
||||||
"Block_user": "封鎖此用戶",
|
|
||||||
"Browser": "瀏覽器",
|
"Browser": "瀏覽器",
|
||||||
"Busy": "忙碌",
|
"Busy": "忙碌",
|
||||||
"Cancel_editing": "取消編輯",
|
"Cancel_editing": "取消編輯",
|
||||||
|
@ -371,7 +370,6 @@
|
||||||
"Two_Factor_Authentication": "雙重認證",
|
"Two_Factor_Authentication": "雙重認證",
|
||||||
"unarchive": "取消封存",
|
"unarchive": "取消封存",
|
||||||
"UNARCHIVE": "取消封存",
|
"UNARCHIVE": "取消封存",
|
||||||
"Unblock_user": "解除封鎖",
|
|
||||||
"Unfollowed_thread": "取消追蹤討論",
|
"Unfollowed_thread": "取消追蹤討論",
|
||||||
"Unmute": "取消靜音",
|
"Unmute": "取消靜音",
|
||||||
"unmuted": "靜音狀態",
|
"unmuted": "靜音狀態",
|
||||||
|
|
|
@ -55,4 +55,15 @@ describe('Test the getFilename', () => {
|
||||||
const filename = getFilename({ type: 'image', mimeType: image_type, title, url: image_url });
|
const filename = getFilename({ type: 'image', mimeType: image_type, title, url: image_url });
|
||||||
expect(filename).toBe('help-image-url.png');
|
expect(filename).toBe('help-image-url.png');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('returns the filename with the gif extension from a gif sent by tenor/giphy', () => {
|
||||||
|
const { image_type, image_url, title } = {
|
||||||
|
title: undefined,
|
||||||
|
image_url: 'https://media4.giphy.com/media/bGtO3RlAPHkeQ/giphy.gif',
|
||||||
|
image_type: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
const filename = getFilename({ type: 'image', mimeType: image_type, title, url: image_url });
|
||||||
|
expect(filename).toBe('giphy.gif');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -68,6 +68,10 @@ export const getFilename = ({
|
||||||
};
|
};
|
||||||
|
|
||||||
const getExtension = (type: MediaTypes, mimeType?: string, url?: string) => {
|
const getExtension = (type: MediaTypes, mimeType?: string, url?: string) => {
|
||||||
|
// support url with gif extension and mimetype undefined, ex.: using the app tenor and giphy.
|
||||||
|
if (url?.split('.').pop() === 'gif') {
|
||||||
|
return 'gif';
|
||||||
|
}
|
||||||
if (!mimeType) {
|
if (!mimeType) {
|
||||||
return defaultType[type];
|
return defaultType[type];
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { themes } from '../../constants';
|
||||||
import { TSupportedThemes } from '../../../theme';
|
import { TSupportedThemes } from '../../../theme';
|
||||||
import UserPreferences from '../userPreferences';
|
import UserPreferences from '../userPreferences';
|
||||||
import ensureSecureProtocol from './ensureSecureProtocol';
|
import ensureSecureProtocol from './ensureSecureProtocol';
|
||||||
|
import log from './log';
|
||||||
|
|
||||||
export const DEFAULT_BROWSER_KEY = 'DEFAULT_BROWSER_KEY';
|
export const DEFAULT_BROWSER_KEY = 'DEFAULT_BROWSER_KEY';
|
||||||
|
|
||||||
|
@ -38,6 +39,16 @@ const appSchemeURL = (url: string, browser: string): string => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const openLink = async (url: string, theme: TSupportedThemes = 'light'): Promise<void> => {
|
const openLink = async (url: string, theme: TSupportedThemes = 'light'): Promise<void> => {
|
||||||
|
const telRegExp = new RegExp(/^(tel:)/);
|
||||||
|
if (telRegExp.test(url)) {
|
||||||
|
try {
|
||||||
|
await Linking.openURL(url);
|
||||||
|
return;
|
||||||
|
} catch (e) {
|
||||||
|
log(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
url = ensureSecureProtocol(url);
|
url = ensureSecureProtocol(url);
|
||||||
try {
|
try {
|
||||||
const browser = UserPreferences.getString(DEFAULT_BROWSER_KEY);
|
const browser = UserPreferences.getString(DEFAULT_BROWSER_KEY);
|
||||||
|
|
|
@ -296,6 +296,10 @@ export const togglePinMessage = (messageId: string, pinned?: boolean) => {
|
||||||
return sdk.post('chat.pinMessage', { messageId });
|
return sdk.post('chat.pinMessage', { messageId });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const reportUser = (userId: string, description: string) =>
|
||||||
|
// RC 6.4.0
|
||||||
|
sdk.post('moderation.reportUser', { userId, description });
|
||||||
|
|
||||||
export const reportMessage = (messageId: string) =>
|
export const reportMessage = (messageId: string) =>
|
||||||
// RC 0.64.0
|
// RC 0.64.0
|
||||||
sdk.post('chat.reportMessage', { messageId, description: 'Message reported by user' });
|
sdk.post('chat.reportMessage', { messageId, description: 'Message reported by user' });
|
||||||
|
|
|
@ -11,6 +11,7 @@ import RoomView from '../views/RoomView';
|
||||||
import RoomsListView from '../views/RoomsListView';
|
import RoomsListView from '../views/RoomsListView';
|
||||||
import RoomActionsView from '../views/RoomActionsView';
|
import RoomActionsView from '../views/RoomActionsView';
|
||||||
import RoomInfoView from '../views/RoomInfoView';
|
import RoomInfoView from '../views/RoomInfoView';
|
||||||
|
import ReportUserView from '../views/ReportUserView';
|
||||||
import RoomInfoEditView from '../views/RoomInfoEditView';
|
import RoomInfoEditView from '../views/RoomInfoEditView';
|
||||||
import RoomMembersView from '../views/RoomMembersView';
|
import RoomMembersView from '../views/RoomMembersView';
|
||||||
import SearchMessagesView from '../views/SearchMessagesView';
|
import SearchMessagesView from '../views/SearchMessagesView';
|
||||||
|
@ -99,6 +100,7 @@ const ChatsStackNavigator = () => {
|
||||||
<ChatsStack.Screen name='RoomActionsView' component={RoomActionsView} options={RoomActionsView.navigationOptions} />
|
<ChatsStack.Screen name='RoomActionsView' component={RoomActionsView} options={RoomActionsView.navigationOptions} />
|
||||||
<ChatsStack.Screen name='SelectListView' component={SelectListView} options={SelectListView.navigationOptions} />
|
<ChatsStack.Screen name='SelectListView' component={SelectListView} options={SelectListView.navigationOptions} />
|
||||||
<ChatsStack.Screen name='RoomInfoView' component={RoomInfoView} />
|
<ChatsStack.Screen name='RoomInfoView' component={RoomInfoView} />
|
||||||
|
<ChatsStack.Screen name='ReportUserView' component={ReportUserView} />
|
||||||
{/* @ts-ignore */}
|
{/* @ts-ignore */}
|
||||||
<ChatsStack.Screen name='RoomInfoEditView' component={RoomInfoEditView} options={RoomInfoEditView.navigationOptions} />
|
<ChatsStack.Screen name='RoomInfoEditView' component={RoomInfoEditView} options={RoomInfoEditView.navigationOptions} />
|
||||||
<ChatsStack.Screen name='ChangeAvatarView' component={ChangeAvatarView} />
|
<ChatsStack.Screen name='ChangeAvatarView' component={ChangeAvatarView} />
|
||||||
|
|
|
@ -15,6 +15,7 @@ import RoomView from '../../views/RoomView';
|
||||||
import RoomsListView from '../../views/RoomsListView';
|
import RoomsListView from '../../views/RoomsListView';
|
||||||
import RoomActionsView from '../../views/RoomActionsView';
|
import RoomActionsView from '../../views/RoomActionsView';
|
||||||
import RoomInfoView from '../../views/RoomInfoView';
|
import RoomInfoView from '../../views/RoomInfoView';
|
||||||
|
import ReportUserView from '../../views/ReportUserView';
|
||||||
import RoomInfoEditView from '../../views/RoomInfoEditView';
|
import RoomInfoEditView from '../../views/RoomInfoEditView';
|
||||||
import ChangeAvatarView from '../../views/ChangeAvatarView';
|
import ChangeAvatarView from '../../views/ChangeAvatarView';
|
||||||
import RoomMembersView from '../../views/RoomMembersView';
|
import RoomMembersView from '../../views/RoomMembersView';
|
||||||
|
@ -118,6 +119,7 @@ const ModalStackNavigator = React.memo(({ navigation }: INavigation) => {
|
||||||
<ModalStack.Screen name='RoomActionsView' component={RoomActionsView} />
|
<ModalStack.Screen name='RoomActionsView' component={RoomActionsView} />
|
||||||
{/* @ts-ignore */}
|
{/* @ts-ignore */}
|
||||||
<ModalStack.Screen name='RoomInfoView' component={RoomInfoView} />
|
<ModalStack.Screen name='RoomInfoView' component={RoomInfoView} />
|
||||||
|
<ModalStack.Screen name='ReportUserView' component={ReportUserView} />
|
||||||
{/* @ts-ignore */}
|
{/* @ts-ignore */}
|
||||||
<ModalStack.Screen name='SelectListView' component={SelectListView} />
|
<ModalStack.Screen name='SelectListView' component={SelectListView} />
|
||||||
<ModalStack.Screen name='RoomInfoEditView' component={RoomInfoEditView} options={RoomInfoEditView.navigationOptions} />
|
<ModalStack.Screen name='RoomInfoEditView' component={RoomInfoEditView} options={RoomInfoEditView.navigationOptions} />
|
||||||
|
|
|
@ -199,6 +199,11 @@ export type ModalStackParamList = {
|
||||||
SupportedVersionsWarning: {
|
SupportedVersionsWarning: {
|
||||||
showCloseButton?: boolean;
|
showCloseButton?: boolean;
|
||||||
};
|
};
|
||||||
|
ReportUserView: {
|
||||||
|
username: string;
|
||||||
|
userId: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MasterDetailInsideStackParamList = {
|
export type MasterDetailInsideStackParamList = {
|
||||||
|
|
|
@ -172,6 +172,11 @@ export type ChatsStackParamList = {
|
||||||
room?: ISubscription;
|
room?: ISubscription;
|
||||||
t?: SubscriptionType;
|
t?: SubscriptionType;
|
||||||
};
|
};
|
||||||
|
ReportUserView: {
|
||||||
|
username: string;
|
||||||
|
userId: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ProfileStackParamList = {
|
export type ProfileStackParamList = {
|
||||||
|
|
|
@ -139,6 +139,7 @@ class DirectoryView extends React.Component<IDirectoryViewProps, IDirectoryViewS
|
||||||
} else if (type === 'teams') {
|
} else if (type === 'teams') {
|
||||||
logEvent(events.DIRECTORY_SEARCH_TEAMS);
|
logEvent(events.DIRECTORY_SEARCH_TEAMS);
|
||||||
}
|
}
|
||||||
|
this.toggleDropdown()
|
||||||
};
|
};
|
||||||
|
|
||||||
toggleWorkspace = () => {
|
toggleWorkspace = () => {
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Text, View } from 'react-native';
|
||||||
|
|
||||||
|
import Avatar from '../../containers/Avatar';
|
||||||
|
import styles from './styles';
|
||||||
|
import { useTheme } from '../../theme';
|
||||||
|
|
||||||
|
const UserInfo = ({ username, name }: { username: string; name: string }) => {
|
||||||
|
const { colors } = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={styles.containerAvatarAndName}>
|
||||||
|
<Avatar text={username} size={32} />
|
||||||
|
<Text style={[styles.nameText, { color: colors.fontDefault }]} numberOfLines={1}>
|
||||||
|
{name || username}
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UserInfo;
|
|
@ -0,0 +1,113 @@
|
||||||
|
import React, { useLayoutEffect, useState } from 'react';
|
||||||
|
import { ScrollView, StatusBar } from 'react-native';
|
||||||
|
import { CompositeNavigationProp, RouteProp, useNavigation, useRoute } from '@react-navigation/native';
|
||||||
|
import { StackNavigationProp } from '@react-navigation/stack';
|
||||||
|
import { useForm } from 'react-hook-form';
|
||||||
|
import * as yup from 'yup';
|
||||||
|
import { yupResolver } from '@hookform/resolvers/yup';
|
||||||
|
|
||||||
|
import log from '../../lib/methods/helpers/log';
|
||||||
|
import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
|
import { useTheme } from '../../theme';
|
||||||
|
import { ChatsStackParamList } from '../../stacks/types';
|
||||||
|
import { MasterDetailInsideStackParamList } from '../../stacks/MasterDetailStack/types';
|
||||||
|
import I18n from '../../i18n';
|
||||||
|
import UserInfo from './UserInfo';
|
||||||
|
import styles from './styles';
|
||||||
|
import { ControlledFormTextInput } from '../../containers/TextInput';
|
||||||
|
import Button from '../../containers/Button';
|
||||||
|
import { useAppSelector } from '../../lib/hooks';
|
||||||
|
import EventEmitter from '../../lib/methods/helpers/events';
|
||||||
|
import { LISTENER } from '../../containers/Toast';
|
||||||
|
import { Services } from '../../lib/services';
|
||||||
|
import KeyboardView from '../../containers/KeyboardView';
|
||||||
|
|
||||||
|
type TReportUserViewNavigationProp = CompositeNavigationProp<
|
||||||
|
StackNavigationProp<ChatsStackParamList, 'ReportUserView'>,
|
||||||
|
StackNavigationProp<MasterDetailInsideStackParamList>
|
||||||
|
>;
|
||||||
|
|
||||||
|
type TReportUserViewRouteProp = RouteProp<ChatsStackParamList, 'ReportUserView'>;
|
||||||
|
|
||||||
|
interface ISubmit {
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const schema = yup.object().shape({
|
||||||
|
description: yup.string().trim().required()
|
||||||
|
});
|
||||||
|
|
||||||
|
const ReportUserView = () => {
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
|
const { colors } = useTheme();
|
||||||
|
const navigation = useNavigation<TReportUserViewNavigationProp>();
|
||||||
|
const { isMasterDetail } = useAppSelector(state => ({ isMasterDetail: state.app.isMasterDetail }));
|
||||||
|
|
||||||
|
const {
|
||||||
|
params: { username, userId, name }
|
||||||
|
} = useRoute<TReportUserViewRouteProp>();
|
||||||
|
|
||||||
|
const {
|
||||||
|
control,
|
||||||
|
handleSubmit,
|
||||||
|
formState: { isValid }
|
||||||
|
} = useForm<ISubmit>({ mode: 'onChange', resolver: yupResolver(schema), defaultValues: { description: '' } });
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
navigation?.setOptions({
|
||||||
|
title: I18n.t('Report_user')
|
||||||
|
});
|
||||||
|
}, [navigation]);
|
||||||
|
|
||||||
|
const submit = async ({ description }: ISubmit) => {
|
||||||
|
try {
|
||||||
|
setLoading(true);
|
||||||
|
await Services.reportUser(userId, description);
|
||||||
|
EventEmitter.emit(LISTENER, { message: I18n.t('Report_sent_successfully') });
|
||||||
|
setLoading(false);
|
||||||
|
if (isMasterDetail) {
|
||||||
|
navigation.navigate('DrawerNavigator');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
navigation.navigate('RoomView');
|
||||||
|
} catch (e) {
|
||||||
|
log(e);
|
||||||
|
setLoading(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<KeyboardView
|
||||||
|
style={{ backgroundColor: colors.auxiliaryBackground }}
|
||||||
|
contentContainerStyle={styles.container}
|
||||||
|
keyboardVerticalOffset={128}
|
||||||
|
>
|
||||||
|
<SafeAreaView style={[styles.containerView, { backgroundColor: colors.auxiliaryBackground }]} testID='report-user-view'>
|
||||||
|
<ScrollView contentContainerStyle={[styles.scroll, { backgroundColor: colors.auxiliaryBackground }]}>
|
||||||
|
<StatusBar />
|
||||||
|
<UserInfo username={username} name={name} />
|
||||||
|
<ControlledFormTextInput
|
||||||
|
name='description'
|
||||||
|
control={control}
|
||||||
|
label={I18n.t('Why_do_you_want_to_report')}
|
||||||
|
multiline
|
||||||
|
inputStyle={styles.textInput}
|
||||||
|
testID='report-user-view-input'
|
||||||
|
containerStyle={styles.containerTextInput}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
title={I18n.t('Report')}
|
||||||
|
type='primary'
|
||||||
|
backgroundColor={colors.dangerColor}
|
||||||
|
disabled={!isValid}
|
||||||
|
onPress={handleSubmit(submit)}
|
||||||
|
testID='report-user-view-submit'
|
||||||
|
loading={loading}
|
||||||
|
/>
|
||||||
|
</ScrollView>
|
||||||
|
</SafeAreaView>
|
||||||
|
</KeyboardView>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ReportUserView;
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
import sharedStyles from '../Styles';
|
||||||
|
|
||||||
|
export default StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
...sharedStyles.container
|
||||||
|
},
|
||||||
|
scroll: {
|
||||||
|
flex: 1
|
||||||
|
},
|
||||||
|
containerView: {
|
||||||
|
padding: 16
|
||||||
|
},
|
||||||
|
containerAvatarAndName: {
|
||||||
|
flexDirection: 'row',
|
||||||
|
marginBottom: 24,
|
||||||
|
alignItems: 'center'
|
||||||
|
},
|
||||||
|
nameText: {
|
||||||
|
marginLeft: 8,
|
||||||
|
fontSize: 16,
|
||||||
|
...sharedStyles.textMedium
|
||||||
|
},
|
||||||
|
containerTextInput: {
|
||||||
|
marginBottom: 24
|
||||||
|
},
|
||||||
|
textInput: {
|
||||||
|
minHeight: 100,
|
||||||
|
maxHeight: 480,
|
||||||
|
height: undefined,
|
||||||
|
textAlignVertical: 'top',
|
||||||
|
padding: 16,
|
||||||
|
paddingTop: 16,
|
||||||
|
paddingBottom: 16
|
||||||
|
}
|
||||||
|
});
|
|
@ -464,6 +464,20 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
handleReportUser = () => {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
const { member } = this.state;
|
||||||
|
const { name, _id: userId, username } = member;
|
||||||
|
if (!name || !userId || !username) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
navigation.navigate('ReportUserView', {
|
||||||
|
name,
|
||||||
|
userId,
|
||||||
|
username
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
toggleEncrypted = async () => {
|
toggleEncrypted = async () => {
|
||||||
logEvent(events.RA_TOGGLE_ENCRYPTED);
|
logEvent(events.RA_TOGGLE_ENCRYPTED);
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
|
@ -863,22 +877,39 @@ class RoomActionsView extends React.Component<IRoomActionsViewProps, IRoomAction
|
||||||
|
|
||||||
if (t === 'd' && !isGroupChat(room)) {
|
if (t === 'd' && !isGroupChat(room)) {
|
||||||
return (
|
return (
|
||||||
<List.Section>
|
<>
|
||||||
<List.Separator />
|
<List.Section>
|
||||||
<List.Item
|
<List.Separator />
|
||||||
title={`${blocker ? 'Unblock' : 'Block'}_user`}
|
<List.Item
|
||||||
onPress={() =>
|
title={`${blocker ? 'Unblock' : 'Block'}`}
|
||||||
this.onPressTouchable({
|
onPress={() =>
|
||||||
event: this.toggleBlockUser
|
this.onPressTouchable({
|
||||||
})
|
event: this.toggleBlockUser
|
||||||
}
|
})
|
||||||
testID='room-actions-block-user'
|
}
|
||||||
left={() => <List.Icon name='ignore' color={themes[theme].dangerColor} />}
|
testID='room-actions-block-user'
|
||||||
showActionIndicator
|
left={() => <List.Icon name='ignore' />}
|
||||||
color={themes[theme].dangerColor}
|
showActionIndicator
|
||||||
/>
|
/>
|
||||||
<List.Separator />
|
<List.Separator />
|
||||||
</List.Section>
|
</List.Section>
|
||||||
|
<List.Section>
|
||||||
|
<List.Separator />
|
||||||
|
<List.Item
|
||||||
|
title={'Report'}
|
||||||
|
onPress={() =>
|
||||||
|
this.onPressTouchable({
|
||||||
|
event: this.handleReportUser
|
||||||
|
})
|
||||||
|
}
|
||||||
|
testID='room-actions-block-user'
|
||||||
|
left={() => <List.Icon name='warning' color={themes[theme].dangerColor} />}
|
||||||
|
showActionIndicator
|
||||||
|
color={themes[theme].dangerColor}
|
||||||
|
/>
|
||||||
|
<List.Separator />
|
||||||
|
</List.Section>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import i18n from '../../../i18n';
|
||||||
import { useVideoConf } from '../../../lib/hooks/useVideoConf';
|
import { useVideoConf } from '../../../lib/hooks/useVideoConf';
|
||||||
import { useTheme } from '../../../theme';
|
import { useTheme } from '../../../theme';
|
||||||
import styles from '../styles';
|
import styles from '../styles';
|
||||||
|
import { compareServerVersion } from '../../../lib/methods/helpers';
|
||||||
|
|
||||||
function BaseButton({
|
function BaseButton({
|
||||||
danger,
|
danger,
|
||||||
|
@ -31,7 +32,9 @@ function BaseButton({
|
||||||
return (
|
return (
|
||||||
<BorderlessButton enabled={enabled} testID={`room-info-view-${iconName}`} onPress={onPress} style={styles.roomButton}>
|
<BorderlessButton enabled={enabled} testID={`room-info-view-${iconName}`} onPress={onPress} style={styles.roomButton}>
|
||||||
<CustomIcon name={iconName} size={30} color={color} />
|
<CustomIcon name={iconName} size={30} color={color} />
|
||||||
<Text style={[styles.roomButtonText, { color }]}>{label}</Text>
|
<Text numberOfLines={1} style={[styles.roomButtonText, { color }]}>
|
||||||
|
{label}
|
||||||
|
</Text>
|
||||||
</BorderlessButton>
|
</BorderlessButton>
|
||||||
);
|
);
|
||||||
return null;
|
return null;
|
||||||
|
@ -59,7 +62,10 @@ interface IRoomInfoButtons {
|
||||||
handleCreateDirectMessage: () => void;
|
handleCreateDirectMessage: () => void;
|
||||||
handleIgnoreUser: () => void;
|
handleIgnoreUser: () => void;
|
||||||
handleBlockUser: () => void;
|
handleBlockUser: () => void;
|
||||||
|
handleReportUser: () => void;
|
||||||
roomFromRid: ISubscription | undefined;
|
roomFromRid: ISubscription | undefined;
|
||||||
|
serverVersion: string | null;
|
||||||
|
itsMe?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const RoomInfoButtons = ({
|
export const RoomInfoButtons = ({
|
||||||
|
@ -71,7 +77,10 @@ export const RoomInfoButtons = ({
|
||||||
handleCreateDirectMessage,
|
handleCreateDirectMessage,
|
||||||
handleIgnoreUser,
|
handleIgnoreUser,
|
||||||
handleBlockUser,
|
handleBlockUser,
|
||||||
roomFromRid
|
handleReportUser,
|
||||||
|
roomFromRid,
|
||||||
|
serverVersion,
|
||||||
|
itsMe
|
||||||
}: IRoomInfoButtons): React.ReactElement => {
|
}: IRoomInfoButtons): React.ReactElement => {
|
||||||
const room = roomFromRid || roomFromProps;
|
const room = roomFromRid || roomFromProps;
|
||||||
// Following the web behavior, when is a DM with myself, shouldn't appear block or ignore option
|
// Following the web behavior, when is a DM with myself, shouldn't appear block or ignore option
|
||||||
|
@ -82,7 +91,9 @@ export const RoomInfoButtons = ({
|
||||||
const isBlocked = room?.blocker;
|
const isBlocked = room?.blocker;
|
||||||
|
|
||||||
const renderIgnoreUser = isDirectFromSaved && !isFromDm && !isDmWithMyself;
|
const renderIgnoreUser = isDirectFromSaved && !isFromDm && !isDmWithMyself;
|
||||||
const renderBlockUser = isDirectFromSaved && isFromDm && !isDmWithMyself;
|
const renderBlockUser = !itsMe && isDirectFromSaved && isFromDm && !isDmWithMyself;
|
||||||
|
const renderReportUser =
|
||||||
|
!itsMe && isDirectFromSaved && !isDmWithMyself && compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '6.4.0');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.roomButtonsContainer}>
|
<View style={styles.roomButtonsContainer}>
|
||||||
|
@ -93,13 +104,18 @@ export const RoomInfoButtons = ({
|
||||||
label={i18n.t(isIgnored ? 'Unignore' : 'Ignore')}
|
label={i18n.t(isIgnored ? 'Unignore' : 'Ignore')}
|
||||||
iconName='ignore'
|
iconName='ignore'
|
||||||
showIcon={!!renderIgnoreUser}
|
showIcon={!!renderIgnoreUser}
|
||||||
danger
|
|
||||||
/>
|
/>
|
||||||
<BaseButton
|
<BaseButton
|
||||||
onPress={handleBlockUser}
|
onPress={handleBlockUser}
|
||||||
label={i18n.t(`${isBlocked ? 'Unblock' : 'Block'}_user`)}
|
label={i18n.t(`${isBlocked ? 'Unblock' : 'Block'}`)}
|
||||||
iconName='ignore'
|
iconName='ignore'
|
||||||
showIcon={!!renderBlockUser}
|
showIcon={!!renderBlockUser}
|
||||||
|
/>
|
||||||
|
<BaseButton
|
||||||
|
onPress={handleReportUser}
|
||||||
|
label={i18n.t('Report')}
|
||||||
|
iconName='warning'
|
||||||
|
showIcon={!!renderReportUser}
|
||||||
danger
|
danger
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -31,8 +31,8 @@ import RoomInfoViewTitle from './components/RoomInfoViewTitle';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
type TRoomInfoViewNavigationProp = CompositeNavigationProp<
|
type TRoomInfoViewNavigationProp = CompositeNavigationProp<
|
||||||
StackNavigationProp<ChatsStackParamList, 'RoomInfoView'>,
|
StackNavigationProp<ChatsStackParamList, 'RoomInfoView'>,
|
||||||
StackNavigationProp<MasterDetailInsideStackParamList>
|
StackNavigationProp<MasterDetailInsideStackParamList>
|
||||||
>;
|
>;
|
||||||
|
|
||||||
type TRoomInfoViewRouteProp = RouteProp<ChatsStackParamList, 'RoomInfoView'>;
|
type TRoomInfoViewRouteProp = RouteProp<ChatsStackParamList, 'RoomInfoView'>;
|
||||||
|
@ -59,6 +59,7 @@ const RoomInfoView = (): React.ReactElement => {
|
||||||
subscribedRoom,
|
subscribedRoom,
|
||||||
usersRoles,
|
usersRoles,
|
||||||
roles,
|
roles,
|
||||||
|
serverVersion,
|
||||||
// permissions
|
// permissions
|
||||||
editRoomPermission,
|
editRoomPermission,
|
||||||
editOmnichannelContact,
|
editOmnichannelContact,
|
||||||
|
@ -68,6 +69,7 @@ const RoomInfoView = (): React.ReactElement => {
|
||||||
isMasterDetail: state.app.isMasterDetail,
|
isMasterDetail: state.app.isMasterDetail,
|
||||||
roles: state.roles,
|
roles: state.roles,
|
||||||
usersRoles: state.usersRoles,
|
usersRoles: state.usersRoles,
|
||||||
|
serverVersion: state.server.version,
|
||||||
// permissions
|
// permissions
|
||||||
editRoomPermission: state.permissions['edit-room'],
|
editRoomPermission: state.permissions['edit-room'],
|
||||||
editOmnichannelContact: state.permissions['edit-omnichannel-contact'],
|
editOmnichannelContact: state.permissions['edit-omnichannel-contact'],
|
||||||
|
@ -275,6 +277,14 @@ const RoomInfoView = (): React.ReactElement => {
|
||||||
if (r?.rid) handleIgnore(roomUser._id, !isIgnored, r?.rid);
|
if (r?.rid) handleIgnore(roomUser._id, !isIgnored, r?.rid);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleReportUser = () => {
|
||||||
|
navigate('ReportUserView', {
|
||||||
|
name: roomUser?.name,
|
||||||
|
userId: roomUser?._id,
|
||||||
|
username: roomUser.username
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ScrollView style={[styles.scroll, { backgroundColor: colors.backgroundColor }]}>
|
<ScrollView style={[styles.scroll, { backgroundColor: colors.backgroundColor }]}>
|
||||||
<StatusBar />
|
<StatusBar />
|
||||||
|
@ -301,10 +311,13 @@ const RoomInfoView = (): React.ReactElement => {
|
||||||
handleBlockUser={handleBlockUser}
|
handleBlockUser={handleBlockUser}
|
||||||
handleCreateDirectMessage={handleCreateDirectMessage}
|
handleCreateDirectMessage={handleCreateDirectMessage}
|
||||||
handleIgnoreUser={handleIgnoreUser}
|
handleIgnoreUser={handleIgnoreUser}
|
||||||
|
handleReportUser={handleReportUser}
|
||||||
isDirect={isDirect}
|
isDirect={isDirect}
|
||||||
room={room || roomUser}
|
room={room || roomUser}
|
||||||
roomUserId={roomUser?._id}
|
roomUserId={roomUser?._id}
|
||||||
roomFromRid={roomFromRid}
|
roomFromRid={roomFromRid}
|
||||||
|
serverVersion={serverVersion}
|
||||||
|
itsMe={itsMe}
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
<RoomInfoViewBody isDirect={isDirect} room={room} roomUser={roomUser} />
|
<RoomInfoViewBody isDirect={isDirect} room={room} roomUser={roomUser} />
|
||||||
|
|
|
@ -79,11 +79,12 @@ export default StyleSheet.create({
|
||||||
},
|
},
|
||||||
roomButton: {
|
roomButton: {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
paddingHorizontal: 20,
|
marginHorizontal: 4,
|
||||||
justifyContent: 'space-between'
|
justifyContent: 'space-between',
|
||||||
|
width: 80
|
||||||
},
|
},
|
||||||
roomButtonText: {
|
roomButtonText: {
|
||||||
marginTop: 5
|
marginTop: 4
|
||||||
},
|
},
|
||||||
roomInfoViewTitleContainer: {
|
roomInfoViewTitleContainer: {
|
||||||
paddingTop: 16,
|
paddingTop: 16,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Q } from '@nozbe/watermelondb';
|
import { Q } from '@nozbe/watermelondb';
|
||||||
|
|
||||||
import { LISTENER } from '../../containers/Toast';
|
import { LISTENER } from '../../containers/Toast';
|
||||||
import { IUser, SubscriptionType, TSubscriptionModel, TUserModel } from '../../definitions';
|
import { IGetRoomRoles, IUser, SubscriptionType, TSubscriptionModel, TUserModel } from '../../definitions';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { getRoomTitle, showConfirmationAlert, showErrorAlert } from '../../lib/methods/helpers';
|
import { getRoomTitle, showConfirmationAlert, showErrorAlert } from '../../lib/methods/helpers';
|
||||||
import EventEmitter from '../../lib/methods/helpers/events';
|
import EventEmitter from '../../lib/methods/helpers/events';
|
||||||
|
@ -18,9 +18,9 @@ const handleGoRoom = (item: TGoRoomItem, isMasterDetail: boolean): void => {
|
||||||
goRoom({ item, isMasterDetail, popToRoot: true });
|
goRoom({ item, isMasterDetail, popToRoot: true });
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchRole = (role: string, selectedUser: TUserModel, roomRoles: any): boolean => {
|
export const fetchRole = (role: string, selectedUser: TUserModel, roomRoles?: IGetRoomRoles[]): boolean => {
|
||||||
const userRoleResult = roomRoles.find((r: any) => r.u._id === selectedUser._id);
|
const userRoleResult = roomRoles?.find((r: any) => r.u._id === selectedUser._id);
|
||||||
return userRoleResult?.roles.includes(role);
|
return !!userRoleResult?.roles.includes(role);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchRoomMembersRoles = async (roomType: TRoomType, rid: string, updateState: any): Promise<void> => {
|
export const fetchRoomMembersRoles = async (roomType: TRoomType, rid: string, updateState: any): Promise<void> => {
|
||||||
|
|
|
@ -13,7 +13,7 @@ import SafeAreaView from '../../containers/SafeAreaView';
|
||||||
import SearchBox from '../../containers/SearchBox';
|
import SearchBox from '../../containers/SearchBox';
|
||||||
import StatusBar from '../../containers/StatusBar';
|
import StatusBar from '../../containers/StatusBar';
|
||||||
import UserItem from '../../containers/UserItem';
|
import UserItem from '../../containers/UserItem';
|
||||||
import { TSubscriptionModel, TUserModel } from '../../definitions';
|
import { IGetRoomRoles, TSubscriptionModel, TUserModel } from '../../definitions';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { useAppSelector, usePermissions } from '../../lib/hooks';
|
import { useAppSelector, usePermissions } from '../../lib/hooks';
|
||||||
import { compareServerVersion, getRoomTitle, isGroupChat } from '../../lib/methods/helpers';
|
import { compareServerVersion, getRoomTitle, isGroupChat } from '../../lib/methods/helpers';
|
||||||
|
@ -50,7 +50,7 @@ interface IRoomMembersViewState {
|
||||||
members: TUserModel[];
|
members: TUserModel[];
|
||||||
room: TSubscriptionModel;
|
room: TSubscriptionModel;
|
||||||
end: boolean;
|
end: boolean;
|
||||||
roomRoles: any;
|
roomRoles?: IGetRoomRoles[];
|
||||||
filter: string;
|
filter: string;
|
||||||
page: number;
|
page: number;
|
||||||
}
|
}
|
||||||
|
@ -93,7 +93,7 @@ const RoomMembersView = (): React.ReactElement => {
|
||||||
members: [],
|
members: [],
|
||||||
room: params.room || ({} as TSubscriptionModel),
|
room: params.room || ({} as TSubscriptionModel),
|
||||||
end: false,
|
end: false,
|
||||||
roomRoles: null,
|
roomRoles: undefined,
|
||||||
filter: '',
|
filter: '',
|
||||||
page: 0
|
page: 0
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,13 +82,13 @@ const Header = React.memo(({ room, thread }: IHeader) => {
|
||||||
<View style={styles.inner}>
|
<View style={styles.inner}>
|
||||||
<Text numberOfLines={1} style={styles.text}>
|
<Text numberOfLines={1} style={styles.text}>
|
||||||
<Text style={[styles.text, { color: textColor }]} numberOfLines={1}>
|
<Text style={[styles.text, { color: textColor }]} numberOfLines={1}>
|
||||||
{I18n.t('Sending_to')}{' '}
|
{I18n.t('Sending_to')}
|
||||||
</Text>
|
|
||||||
<CustomIcon name={icon} size={16} color={textColor} />
|
|
||||||
<Text style={[styles.name, { color: textColor }]} numberOfLines={1}>
|
|
||||||
{title}
|
|
||||||
</Text>
|
</Text>
|
||||||
</Text>
|
</Text>
|
||||||
|
<CustomIcon name={icon} size={16} color={textColor} />
|
||||||
|
<Text style={[styles.name, { color: textColor }]} numberOfLines={1}>
|
||||||
|
{title}
|
||||||
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
|
@ -76,7 +76,6 @@ describe('Join room from directory', () => {
|
||||||
.withTimeout(2000);
|
.withTimeout(2000);
|
||||||
await element(by.id('directory-view-dropdown')).tap();
|
await element(by.id('directory-view-dropdown')).tap();
|
||||||
await element(by.label('Users')).atIndex(0).tap();
|
await element(by.label('Users')).atIndex(0).tap();
|
||||||
await element(by.label('Search by')).atIndex(0).tap();
|
|
||||||
await navigateToRoom(otherUser.username);
|
await navigateToRoom(otherUser.username);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -88,7 +87,6 @@ describe('Join room from directory', () => {
|
||||||
.withTimeout(2000);
|
.withTimeout(2000);
|
||||||
await element(by.id('directory-view-dropdown')).tap();
|
await element(by.id('directory-view-dropdown')).tap();
|
||||||
await element(by.label('Teams')).atIndex(0).tap();
|
await element(by.label('Teams')).atIndex(0).tap();
|
||||||
await element(by.label('Search by')).atIndex(0).tap();
|
|
||||||
await navigateToRoom(team);
|
await navigateToRoom(team);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -47,11 +47,12 @@ describe('Ignore/Block User', () => {
|
||||||
await navigateToInfoView();
|
await navigateToInfoView();
|
||||||
});
|
});
|
||||||
it('should block user', async () => {
|
it('should block user', async () => {
|
||||||
await waitFor(element(by.id('room-info-view-ignore').withDescendant(by[textMatcher]('Block user'))))
|
await sleep(300);
|
||||||
|
await waitFor(element(by.id('room-info-view-ignore').withDescendant(by[textMatcher]('Block'))))
|
||||||
.toBeVisible()
|
.toBeVisible()
|
||||||
.withTimeout(2000);
|
.withTimeout(2000);
|
||||||
await element(by.id('room-info-view-ignore')).tap();
|
await element(by.id('room-info-view-ignore')).tap();
|
||||||
await waitFor(element(by.id('room-info-view-ignore').withDescendant(by[textMatcher]('Unblock user'))))
|
await waitFor(element(by.id('room-info-view-ignore').withDescendant(by[textMatcher]('Unblock'))))
|
||||||
.toExist()
|
.toExist()
|
||||||
.withTimeout(2000);
|
.withTimeout(2000);
|
||||||
await tapBack();
|
await tapBack();
|
||||||
|
@ -67,7 +68,7 @@ describe('Ignore/Block User', () => {
|
||||||
await sleep(300); // wait for navigation animation
|
await sleep(300); // wait for navigation animation
|
||||||
await tapAndWaitFor(
|
await tapAndWaitFor(
|
||||||
element(by.id('room-info-view-ignore')),
|
element(by.id('room-info-view-ignore')),
|
||||||
element(by.id('room-info-view-ignore').withDescendant(by[textMatcher]('Block user'))),
|
element(by.id('room-info-view-ignore').withDescendant(by[textMatcher]('Block'))),
|
||||||
2000
|
2000
|
||||||
);
|
);
|
||||||
await tapBack();
|
await tapBack();
|
||||||
|
@ -124,5 +125,59 @@ describe('Ignore/Block User', () => {
|
||||||
.withTimeout(2000);
|
.withTimeout(2000);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('Report user', () => {
|
||||||
|
it('should go to user info view from a DM', async () => {
|
||||||
|
await tapBack();
|
||||||
|
await sleep(300);
|
||||||
|
await navigateToRoom(otherUser.username);
|
||||||
|
await navigateToInfoView();
|
||||||
|
});
|
||||||
|
it('should report a user from a DM', async () => {
|
||||||
|
await waitFor(element(by.id('room-info-view-warning').withDescendant(by[textMatcher]('Report'))))
|
||||||
|
.toBeVisible()
|
||||||
|
.withTimeout(2000);
|
||||||
|
await element(by.id('room-info-view-warning')).tap();
|
||||||
|
await sleep(300);
|
||||||
|
await waitFor(element(by.id('report-user-view')))
|
||||||
|
.toBeVisible()
|
||||||
|
.withTimeout(2000);
|
||||||
|
await waitFor(element(by.id('report-user-view-input')))
|
||||||
|
.toBeVisible()
|
||||||
|
.withTimeout(2000);
|
||||||
|
await element(by.id('report-user-view-input')).replaceText('e2e test');
|
||||||
|
await element(by.id('report-user-view-submit')).tap();
|
||||||
|
await sleep(500);
|
||||||
|
await checkRoomTitle(otherUser.username);
|
||||||
|
});
|
||||||
|
it('should go to user info view from a channel', async () => {
|
||||||
|
await tapBack();
|
||||||
|
await sleep(300);
|
||||||
|
await navigateToRoom(room);
|
||||||
|
await waitFor(element(by[textMatcher](otherUser.username)).atIndex(0))
|
||||||
|
.toExist()
|
||||||
|
.withTimeout(30000);
|
||||||
|
await element(by[textMatcher](otherUser.username)).atIndex(0).tap();
|
||||||
|
await waitFor(element(by.id('room-info-view')))
|
||||||
|
.toExist()
|
||||||
|
.withTimeout(2000);
|
||||||
|
});
|
||||||
|
it('should report a user from a channel', async () => {
|
||||||
|
await waitFor(element(by.id('room-info-view-warning').withDescendant(by[textMatcher]('Report'))))
|
||||||
|
.toBeVisible()
|
||||||
|
.withTimeout(2000);
|
||||||
|
await element(by.id('room-info-view-warning')).tap();
|
||||||
|
await sleep(300);
|
||||||
|
await waitFor(element(by.id('report-user-view')))
|
||||||
|
.toBeVisible()
|
||||||
|
.withTimeout(2000);
|
||||||
|
await waitFor(element(by.id('report-user-view-input')))
|
||||||
|
.toBeVisible()
|
||||||
|
.withTimeout(2000);
|
||||||
|
await element(by.id('report-user-view-input')).replaceText('e2e test');
|
||||||
|
await element(by.id('report-user-view-submit')).tap();
|
||||||
|
await sleep(500);
|
||||||
|
await checkRoomTitle(room);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1766,7 +1766,7 @@
|
||||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||||
MARKETING_VERSION = 4.44.2;
|
MARKETING_VERSION = 4.45.0;
|
||||||
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG";
|
||||||
|
@ -1805,7 +1805,7 @@
|
||||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||||
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
IPHONEOS_DEPLOYMENT_TARGET = 12.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
|
||||||
MARKETING_VERSION = 4.44.2;
|
MARKETING_VERSION = 4.45.0;
|
||||||
MTL_FAST_MATH = YES;
|
MTL_FAST_MATH = YES;
|
||||||
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE";
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = chat.rocket.reactnative.NotificationService;
|
PRODUCT_BUNDLE_IDENTIFIER = chat.rocket.reactnative.NotificationService;
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>4.44.2</string>
|
<string>4.45.0</string>
|
||||||
<key>CFBundleSignature</key>
|
<key>CFBundleSignature</key>
|
||||||
<string>????</string>
|
<string>????</string>
|
||||||
<key>CFBundleURLTypes</key>
|
<key>CFBundleURLTypes</key>
|
||||||
|
@ -54,6 +54,7 @@
|
||||||
<string>googlechromes</string>
|
<string>googlechromes</string>
|
||||||
<string>firefox</string>
|
<string>firefox</string>
|
||||||
<string>brave</string>
|
<string>brave</string>
|
||||||
|
<string>tel</string>
|
||||||
</array>
|
</array>
|
||||||
<key>LSRequiresIPhoneOS</key>
|
<key>LSRequiresIPhoneOS</key>
|
||||||
<true/>
|
<true/>
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>XPC!</string>
|
<string>XPC!</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>4.44.2</string>
|
<string>4.45.0</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
<key>KeychainGroup</key>
|
<key>KeychainGroup</key>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "rocket-chat-reactnative",
|
"name": "rocket-chat-reactnative",
|
||||||
"version": "4.44.2",
|
"version": "4.45.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-native start",
|
"start": "react-native start",
|
||||||
|
|
Loading…
Reference in New Issue