Merge branch 'develop' into migrate-auto-translate-view-hooks
This commit is contained in:
commit
0da22bf336
|
@ -3,7 +3,7 @@ defaults: &defaults
|
||||||
|
|
||||||
macos: &macos
|
macos: &macos
|
||||||
macos:
|
macos:
|
||||||
xcode: "13.3.0"
|
xcode: "14.2.0"
|
||||||
resource_class: large
|
resource_class: large
|
||||||
|
|
||||||
bash-env: &bash-env
|
bash-env: &bash-env
|
||||||
|
@ -51,14 +51,14 @@ save-gems-cache: &save-gems-cache
|
||||||
update-fastlane-ios: &update-fastlane-ios
|
update-fastlane-ios: &update-fastlane-ios
|
||||||
name: Update Fastlane
|
name: Update Fastlane
|
||||||
command: |
|
command: |
|
||||||
echo "ruby-2.6.4" > ~/.ruby-version
|
echo "ruby-2.7.7" > ~/.ruby-version
|
||||||
bundle install
|
bundle install
|
||||||
working_directory: ios
|
working_directory: ios
|
||||||
|
|
||||||
update-fastlane-android: &update-fastlane-android
|
update-fastlane-android: &update-fastlane-android
|
||||||
name: Update Fastlane
|
name: Update Fastlane
|
||||||
command: |
|
command: |
|
||||||
echo "ruby-2.6.4" > ~/.ruby-version
|
echo "ruby-2.7.7" > ~/.ruby-version
|
||||||
bundle install
|
bundle install
|
||||||
working_directory: android
|
working_directory: android
|
||||||
|
|
||||||
|
@ -118,26 +118,26 @@ commands:
|
||||||
if [[ $CIRCLE_JOB == "android-build-official" ]]; then
|
if [[ $CIRCLE_JOB == "android-build-official" ]]; then
|
||||||
echo -e "APPLICATION_ID=chat.rocket.android" >> ./gradle.properties
|
echo -e "APPLICATION_ID=chat.rocket.android" >> ./gradle.properties
|
||||||
echo -e "BugsnagAPIKey=$BUGSNAG_KEY_OFFICIAL" >> ./gradle.properties
|
echo -e "BugsnagAPIKey=$BUGSNAG_KEY_OFFICIAL" >> ./gradle.properties
|
||||||
echo $CHAT_ROCKET_ANDROID_STORE_FILE_BASE64_JKS | base64 --decode > ./app/$KEYSTORE_OFFICIAL
|
echo $KEYSTORE_OFFICIAL_BASE64 | base64 --decode > ./app/$KEYSTORE_OFFICIAL
|
||||||
echo -e "KEYSTORE=$KEYSTORE_OFFICIAL" >> ./gradle.properties
|
echo -e "KEYSTORE=$KEYSTORE_OFFICIAL" >> ./gradle.properties
|
||||||
echo -e "KEYSTORE_PASSWORD=$CHAT_ROCKET_ANDROID_STORE_PASSWORD" >> ./gradle.properties
|
echo -e "KEYSTORE_PASSWORD=$KEYSTORE_OFFICIAL_PASSWORD" >> ./gradle.properties
|
||||||
echo -e "KEY_ALIAS=$CHAT_ROCKET_ANDROID_KEY_ALIAS" >> ./gradle.properties
|
echo -e "KEY_ALIAS=$KEYSTORE_OFFICIAL_ALIAS" >> ./gradle.properties
|
||||||
echo -e "KEY_PASSWORD=$CHAT_ROCKET_ANDROID_KEY_PASSWORD" >> ./gradle.properties
|
echo -e "KEY_PASSWORD=$KEYSTORE_OFFICIAL_PASSWORD" >> ./gradle.properties
|
||||||
else
|
else
|
||||||
echo -e "APPLICATION_ID=chat.rocket.reactnative" >> ./gradle.properties
|
echo -e "APPLICATION_ID=chat.rocket.reactnative" >> ./gradle.properties
|
||||||
echo -e "BugsnagAPIKey=$BUGSNAG_KEY" >> ./gradle.properties
|
echo -e "BugsnagAPIKey=$BUGSNAG_KEY" >> ./gradle.properties
|
||||||
echo $KEYSTORE_BASE64 | base64 --decode > ./app/$KEYSTORE
|
echo $KEYSTORE_EXPERIMENTAL_BASE64 | base64 --decode > ./app/$KEYSTORE_EXPERIMENTAL
|
||||||
echo -e "KEYSTORE=$KEYSTORE" >> ./gradle.properties
|
echo -e "KEYSTORE=$KEYSTORE_EXPERIMENTAL" >> ./gradle.properties
|
||||||
echo -e "KEYSTORE_PASSWORD=$KEYSTORE_PASSWORD" >> ./gradle.properties
|
echo -e "KEYSTORE_PASSWORD=$KEYSTORE_EXPERIMENTAL_PASSWORD" >> ./gradle.properties
|
||||||
echo -e "KEY_ALIAS=$KEY_ALIAS" >> ./gradle.properties
|
echo -e "KEY_ALIAS=$KEYSTORE_EXPERIMENTAL_ALIAS" >> ./gradle.properties
|
||||||
echo -e "KEY_PASSWORD=$KEYSTORE_PASSWORD" >> ./gradle.properties
|
echo -e "KEY_PASSWORD=$KEYSTORE_EXPERIMENTAL_PASSWORD" >> ./gradle.properties
|
||||||
fi
|
fi
|
||||||
working_directory: android
|
working_directory: android
|
||||||
|
|
||||||
- run:
|
- run:
|
||||||
name: Set Google Services
|
name: Set Google Services
|
||||||
command: |
|
command: |
|
||||||
if [[ $KEYSTORE ]]; then
|
if [[ $GOOGLE_SERVICES_ANDROID ]]; then
|
||||||
echo $GOOGLE_SERVICES_ANDROID | base64 --decode > google-services.json
|
echo $GOOGLE_SERVICES_ANDROID | base64 --decode > google-services.json
|
||||||
fi
|
fi
|
||||||
working_directory: android/app
|
working_directory: android/app
|
||||||
|
@ -151,7 +151,7 @@ commands:
|
||||||
if [[ $CIRCLE_JOB == "android-build-experimental" || "android-automatic-build-experimental" ]]; then
|
if [[ $CIRCLE_JOB == "android-build-experimental" || "android-automatic-build-experimental" ]]; then
|
||||||
./gradlew bundleExperimentalPlayRelease
|
./gradlew bundleExperimentalPlayRelease
|
||||||
fi
|
fi
|
||||||
if [[ ! $KEYSTORE ]]; then
|
if [[ ! $GOOGLE_SERVICES_ANDROID ]]; then
|
||||||
./gradlew assembleExperimentalPlayDebug
|
./gradlew assembleExperimentalPlayDebug
|
||||||
fi
|
fi
|
||||||
working_directory: android
|
working_directory: android
|
||||||
|
@ -200,8 +200,12 @@ commands:
|
||||||
- run:
|
- run:
|
||||||
name: Set Google Services
|
name: Set Google Services
|
||||||
command: |
|
command: |
|
||||||
if [[ $KEYSTORE ]]; then
|
if [[ $APP_STORE_CONNECT_API_KEY_BASE64 ]]; then
|
||||||
echo $GOOGLE_SERVICES_IOS | base64 --decode > GoogleService-Info.plist
|
if [[ $CIRCLE_JOB == "ios-build-official" ]]; then
|
||||||
|
echo $GOOGLE_SERVICES_IOS | base64 --decode > GoogleService-Info.plist
|
||||||
|
else
|
||||||
|
echo $GOOGLE_SERVICES_IOS_EXPERIMENTAL | base64 --decode > GoogleService-Info.plist
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
working_directory: ios
|
working_directory: ios
|
||||||
- run:
|
- run:
|
||||||
|
@ -223,12 +227,12 @@ commands:
|
||||||
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./NotificationService/Info.plist
|
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./NotificationService/Info.plist
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ $APP_STORE_CONNECT_API_BASE64 ]]; then
|
if [[ $APP_STORE_CONNECT_API_KEY_BASE64 ]]; then
|
||||||
echo $APP_STORE_CONNECT_API_BASE64 | base64 --decode > ./fastlane/app_store_connect_api_key.p8
|
echo $APP_STORE_CONNECT_API_KEY_BASE64 | base64 --decode > ./fastlane/app_store_connect_api_key.p8
|
||||||
if [[ $CIRCLE_JOB == "ios-build-official" ]]; then
|
if [[ $CIRCLE_JOB == "ios-build-official" ]]; then
|
||||||
bundle exec fastlane ios build_official
|
bundle exec fastlane ios build_official
|
||||||
else
|
else
|
||||||
if [[ $KEYSTORE ]]; then
|
if [[ $APP_STORE_CONNECT_API_KEY_BASE64 ]]; then
|
||||||
bundle exec fastlane ios build_experimental
|
bundle exec fastlane ios build_experimental
|
||||||
else
|
else
|
||||||
bundle exec fastlane ios build_fork
|
bundle exec fastlane ios build_fork
|
||||||
|
@ -318,7 +322,7 @@ commands:
|
||||||
- run:
|
- run:
|
||||||
name: Fastlane Tesflight Upload
|
name: Fastlane Tesflight Upload
|
||||||
command: |
|
command: |
|
||||||
echo $APP_STORE_CONNECT_API_BASE64 | base64 --decode > ./fastlane/app_store_connect_api_key.p8
|
echo $APP_STORE_CONNECT_API_KEY_BASE64 | base64 --decode > ./fastlane/app_store_connect_api_key.p8
|
||||||
bundle exec fastlane ios beta official:<< parameters.official >>
|
bundle exec fastlane ios beta official:<< parameters.official >>
|
||||||
working_directory: ios
|
working_directory: ios
|
||||||
- save_cache: *save-gems-cache
|
- save_cache: *save-gems-cache
|
||||||
|
|
|
@ -2,7 +2,7 @@ module.exports = {
|
||||||
settings: {
|
settings: {
|
||||||
'import/resolver': {
|
'import/resolver': {
|
||||||
node: {
|
node: {
|
||||||
extensions: ['.ts', '.tsx', '.js', '.ios.js', '.android.js', '.native.js']
|
extensions: ['.ts', '.tsx', '.js', '.ios.js', '.android.js', '.native.js', '.ios.tsx', '.android.tsx']
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
2.7.4
|
2.7.7
|
||||||
|
|
2
Gemfile
2
Gemfile
|
@ -1,4 +1,4 @@
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
|
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
|
||||||
ruby '2.7.4'
|
ruby '2.7.7'
|
||||||
gem 'cocoapods', '~> 1.11', '>= 1.11.2'
|
gem 'cocoapods', '~> 1.11', '>= 1.11.2'
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -147,7 +147,7 @@ android {
|
||||||
minSdkVersion rootProject.ext.minSdkVersion
|
minSdkVersion rootProject.ext.minSdkVersion
|
||||||
targetSdkVersion rootProject.ext.targetSdkVersion
|
targetSdkVersion rootProject.ext.targetSdkVersion
|
||||||
versionCode VERSIONCODE as Integer
|
versionCode VERSIONCODE as Integer
|
||||||
versionName "4.33.0"
|
versionName "4.36.0"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
if (!isFoss) {
|
if (!isFoss) {
|
||||||
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
|
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
|
||||||
|
@ -357,9 +357,6 @@ dependencies {
|
||||||
playImplementation project(':@react-native-firebase_app')
|
playImplementation project(':@react-native-firebase_app')
|
||||||
playImplementation project(':@react-native-firebase_analytics')
|
playImplementation project(':@react-native-firebase_analytics')
|
||||||
playImplementation project(':@react-native-firebase_crashlytics')
|
playImplementation project(':@react-native-firebase_crashlytics')
|
||||||
implementation(project(':react-native-jitsi-meet')) { // https://github.com/skrafft/react-native-jitsi-meet#side-note
|
|
||||||
exclude group: 'com.facebook.react',module:'react-native-svg'
|
|
||||||
}
|
|
||||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||||
|
|
||||||
//noinspection GradleDynamicVersion
|
//noinspection GradleDynamicVersion
|
||||||
|
|
|
@ -1,25 +0,0 @@
|
||||||
package chat.rocket.reactnative;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
|
|
||||||
import com.facebook.react.ReactInstanceManager;
|
|
||||||
|
|
||||||
public class MainDebugApplication extends MainApplication {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate() {
|
|
||||||
super.onCreate();
|
|
||||||
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
|
|
||||||
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
|
||||||
*
|
|
||||||
* @param context
|
|
||||||
* @param reactInstanceManager
|
|
||||||
*/
|
|
||||||
private static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
|
|
||||||
ReactNativeFlipper.initializeFlipper(context, reactInstanceManager);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -5,6 +5,21 @@
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
|
||||||
|
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||||
|
<uses-permission android:name="android.permission.VIDEO_CAPTURE" />
|
||||||
|
<uses-permission android:name="android.permission.AUDIO_CAPTURE" />
|
||||||
|
|
||||||
|
<!-- permissions related to jitsi call -->
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="30" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" android:maxSdkVersion="30" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" android:usesPermissionFlags="neverForLocation" tools:targetApi="s" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
|
||||||
|
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
|
||||||
|
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" android:maxSdkVersion="28"/>
|
||||||
|
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" tools:targetApi="Q"/>
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name="chat.rocket.reactnative.MainApplication"
|
android:name="chat.rocket.reactnative.MainApplication"
|
||||||
android:allowBackup="false"
|
android:allowBackup="false"
|
||||||
|
@ -14,6 +29,7 @@
|
||||||
android:requestLegacyExternalStorage="true"
|
android:requestLegacyExternalStorage="true"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/BootTheme"
|
android:theme="@style/BootTheme"
|
||||||
|
android:hardwareAccelerated="true"
|
||||||
tools:replace="android:allowBackup">
|
tools:replace="android:allowBackup">
|
||||||
<activity
|
<activity
|
||||||
android:name="chat.rocket.reactnative.MainActivity"
|
android:name="chat.rocket.reactnative.MainActivity"
|
||||||
|
@ -69,5 +85,10 @@
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
</application>
|
||||||
|
<queries>
|
||||||
|
<package android:name="org.jitsi.meet" />
|
||||||
|
<intent>
|
||||||
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
</intent>
|
||||||
|
</queries>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
Binary file not shown.
|
@ -9,13 +9,16 @@ 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.react.config.ReactFeatureFlags;
|
import com.facebook.react.config.ReactFeatureFlags;
|
||||||
|
import com.facebook.react.ReactInstanceManager;
|
||||||
import com.facebook.soloader.SoLoader;
|
import com.facebook.soloader.SoLoader;
|
||||||
import com.reactnativecommunity.viewpager.RNCViewPagerPackage;
|
import com.reactnativecommunity.viewpager.RNCViewPagerPackage;
|
||||||
import com.facebook.react.bridge.JSIModulePackage;
|
import com.facebook.react.bridge.JSIModulePackage;
|
||||||
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
|
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
|
||||||
|
import android.content.Context;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import expo.modules.ApplicationLifecycleDispatcher;
|
import expo.modules.ApplicationLifecycleDispatcher;
|
||||||
import expo.modules.ReactNativeHostWrapper;
|
import expo.modules.ReactNativeHostWrapper;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -76,6 +79,7 @@ public class MainApplication extends Application implements ReactApplication {
|
||||||
// If you opted-in for the New Architecture, we enable the TurboModule system
|
// If you opted-in for the New Architecture, we enable the TurboModule system
|
||||||
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||||
SoLoader.init(this, /* native exopackage */ false);
|
SoLoader.init(this, /* native exopackage */ false);
|
||||||
|
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||||
ApplicationLifecycleDispatcher.onApplicationCreate(this);
|
ApplicationLifecycleDispatcher.onApplicationCreate(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,4 +88,35 @@ public class MainApplication extends Application implements ReactApplication {
|
||||||
super.onConfigurationChanged(newConfig);
|
super.onConfigurationChanged(newConfig);
|
||||||
ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig);
|
ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
|
||||||
|
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||||
|
*
|
||||||
|
* @param context
|
||||||
|
* @param reactInstanceManager
|
||||||
|
*/
|
||||||
|
private static void initializeFlipper(
|
||||||
|
Context context, ReactInstanceManager reactInstanceManager) {
|
||||||
|
if (BuildConfig.DEBUG) {
|
||||||
|
try {
|
||||||
|
/*
|
||||||
|
We use reflection here to pick up the class that initializes Flipper,
|
||||||
|
since Flipper library is not available in release mode
|
||||||
|
*/
|
||||||
|
Class<?> aClass = Class.forName("chat.rocket.reactnative.ReactNativeFlipper");
|
||||||
|
aClass
|
||||||
|
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
|
||||||
|
.invoke(null, context, reactInstanceManager);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,8 +26,6 @@ buildscript {
|
||||||
kotlinVersion = '1.6.10'
|
kotlinVersion = '1.6.10'
|
||||||
supportLibVersion = "28.0.0"
|
supportLibVersion = "28.0.0"
|
||||||
libre_build = !(isPlay.toBoolean())
|
libre_build = !(isPlay.toBoolean())
|
||||||
jitsi_url = "https://github.com/RocketChat/jitsi-maven-repository/raw/master/releases"
|
|
||||||
jitsi_version = "3.7.0"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
@ -68,9 +66,6 @@ allprojects {
|
||||||
url "$rootDir/../node_modules/detox/Detox-android"
|
url "$rootDir/../node_modules/detox/Detox-android"
|
||||||
}
|
}
|
||||||
|
|
||||||
maven {
|
|
||||||
url jitsi_url
|
|
||||||
}
|
|
||||||
mavenCentral {
|
mavenCentral {
|
||||||
content {
|
content {
|
||||||
excludeGroup "com.facebook.react"
|
excludeGroup "com.facebook.react"
|
||||||
|
|
|
@ -23,7 +23,7 @@ android.useAndroidX=true
|
||||||
android.enableJetifier=true
|
android.enableJetifier=true
|
||||||
|
|
||||||
# Version of flipper SDK to use with React Native
|
# Version of flipper SDK to use with React Native
|
||||||
FLIPPER_VERSION=0.125.0
|
FLIPPER_VERSION=0.175.0
|
||||||
|
|
||||||
# Use this property to specify which architecture you want to build.
|
# Use this property to specify which architecture you want to build.
|
||||||
# You can also override it from the CLI using
|
# You can also override it from the CLI using
|
||||||
|
|
|
@ -28,7 +28,9 @@ export const ROOM = createRequestTypes('ROOM', [
|
||||||
'DELETE',
|
'DELETE',
|
||||||
'REMOVED',
|
'REMOVED',
|
||||||
'FORWARD',
|
'FORWARD',
|
||||||
'USER_TYPING'
|
'USER_TYPING',
|
||||||
|
'HISTORY_REQUEST',
|
||||||
|
'HISTORY_FINISHED'
|
||||||
]);
|
]);
|
||||||
export const INQUIRY = createRequestTypes('INQUIRY', [
|
export const INQUIRY = createRequestTypes('INQUIRY', [
|
||||||
...defaultTypes,
|
...defaultTypes,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { Action } from 'redux';
|
import { Action } from 'redux';
|
||||||
|
|
||||||
import { ERoomType } from '../definitions/ERoomType';
|
import { ERoomType, RoomType } from '../definitions';
|
||||||
import { ROOM } from './actionsTypes';
|
import { ROOM } from './actionsTypes';
|
||||||
|
|
||||||
// TYPE RETURN RELATED
|
// TYPE RETURN RELATED
|
||||||
|
@ -44,7 +44,24 @@ interface IUserTyping extends Action {
|
||||||
status: boolean;
|
status: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TActionsRoom = TSubscribeRoom & TUnsubscribeRoom & ILeaveRoom & IDeleteRoom & IForwardRoom & IUserTyping;
|
export interface IRoomHistoryRequest extends Action {
|
||||||
|
rid: string;
|
||||||
|
t: RoomType;
|
||||||
|
loaderId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IRoomHistoryFinished extends Action {
|
||||||
|
loaderId: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type TActionsRoom = TSubscribeRoom &
|
||||||
|
TUnsubscribeRoom &
|
||||||
|
ILeaveRoom &
|
||||||
|
IDeleteRoom &
|
||||||
|
IForwardRoom &
|
||||||
|
IUserTyping &
|
||||||
|
IRoomHistoryRequest &
|
||||||
|
IRoomHistoryFinished;
|
||||||
|
|
||||||
export function subscribeRoom(rid: string): TSubscribeRoom {
|
export function subscribeRoom(rid: string): TSubscribeRoom {
|
||||||
return {
|
return {
|
||||||
|
@ -99,3 +116,19 @@ export function userTyping(rid: string, status = true): IUserTyping {
|
||||||
status
|
status
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function roomHistoryRequest({ rid, t, loaderId }: { rid: string; t: RoomType; loaderId: string }): IRoomHistoryRequest {
|
||||||
|
return {
|
||||||
|
type: ROOM.HISTORY_REQUEST,
|
||||||
|
rid,
|
||||||
|
t,
|
||||||
|
loaderId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function roomHistoryFinished({ loaderId }: { loaderId: string }): IRoomHistoryFinished {
|
||||||
|
return {
|
||||||
|
type: ROOM.HISTORY_FINISHED,
|
||||||
|
loaderId
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -122,7 +122,6 @@ const ActionSheetContentWithInputAndSubmit = ({
|
||||||
}}
|
}}
|
||||||
testID={testID}
|
testID={testID}
|
||||||
secureTextEntry={secureTextEntry}
|
secureTextEntry={secureTextEntry}
|
||||||
inputStyle={{ borderWidth: 2 }}
|
|
||||||
bottomSheet={isIOS}
|
bottomSheet={isIOS}
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { ViewStyle } from 'react-native';
|
||||||
|
|
||||||
import { TGetCustomEmoji } from '../../definitions/IEmoji';
|
import { TGetCustomEmoji } from '../../definitions/IEmoji';
|
||||||
|
|
||||||
export interface IAvatar {
|
export interface IAvatar {
|
||||||
server?: string;
|
server?: string;
|
||||||
style?: any;
|
style?: ViewStyle;
|
||||||
text?: string;
|
text?: string;
|
||||||
avatar?: string;
|
avatar?: string;
|
||||||
emoji?: string;
|
emoji?: string;
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
export const mappedIcons = {
|
export const mappedIcons = {
|
||||||
'lamp-bulb': 59812,
|
'lamp-bulb': 59836,
|
||||||
|
'phone-in': 59835,
|
||||||
'basketball': 59776,
|
'basketball': 59776,
|
||||||
'percentage': 59777,
|
'percentage': 59777,
|
||||||
|
'glasses': 59812,
|
||||||
'burger': 59813,
|
'burger': 59813,
|
||||||
'leaf': 59814,
|
'leaf': 59814,
|
||||||
'airplane': 59815,
|
'airplane': 59815,
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -12,7 +12,6 @@ import { themes } from '../../lib/constants';
|
||||||
import { useTheme } from '../../theme';
|
import { useTheme } from '../../theme';
|
||||||
import { ROW_HEIGHT } from '../RoomItem';
|
import { ROW_HEIGHT } from '../RoomItem';
|
||||||
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
||||||
import Navigation from '../../lib/navigation/appNavigation';
|
|
||||||
import { useOrientation } from '../../dimensions';
|
import { useOrientation } from '../../dimensions';
|
||||||
import { IApplicationState, ISubscription, SubscriptionType } from '../../definitions';
|
import { IApplicationState, ISubscription, SubscriptionType } from '../../definitions';
|
||||||
|
|
||||||
|
@ -98,12 +97,7 @@ const NotifierComponent = React.memo(({ notification, isMasterDetail }: INotifie
|
||||||
prid
|
prid
|
||||||
};
|
};
|
||||||
|
|
||||||
if (isMasterDetail) {
|
goRoom({ item, isMasterDetail, jumpToMessageId: _id, popToRoot: true });
|
||||||
Navigation.navigate('DrawerNavigator');
|
|
||||||
} else {
|
|
||||||
Navigation.navigate('RoomsListView');
|
|
||||||
}
|
|
||||||
goRoom({ item, isMasterDetail, jumpToMessageId: _id });
|
|
||||||
hideNotification();
|
hideNotification();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -124,6 +118,7 @@ const NotifierComponent = React.memo(({ notification, isMasterDetail }: INotifie
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
hitSlop={BUTTON_HIT_SLOP}
|
hitSlop={BUTTON_HIT_SLOP}
|
||||||
background={Touchable.SelectableBackgroundBorderless()}
|
background={Touchable.SelectableBackgroundBorderless()}
|
||||||
|
testID={`in-app-notification-${text}`}
|
||||||
>
|
>
|
||||||
<>
|
<>
|
||||||
<Avatar text={avatar} size={AVATAR_SIZE} type={type} rid={rid} style={styles.avatar} />
|
<Avatar text={avatar} size={AVATAR_SIZE} type={type} rid={rid} style={styles.avatar} />
|
||||||
|
|
|
@ -1,56 +1,50 @@
|
||||||
import React, { memo, useEffect } from 'react';
|
import React, { memo, useEffect } from 'react';
|
||||||
import { Easing, Notifier, NotifierRoot } from 'react-native-notifier';
|
import { Easing, Notifier, NotifierRoot } from 'react-native-notifier';
|
||||||
import { connect } from 'react-redux';
|
|
||||||
import { dequal } from 'dequal';
|
|
||||||
|
|
||||||
import NotifierComponent, { INotifierComponent } from './NotifierComponent';
|
import NotifierComponent, { INotifierComponent } from './NotifierComponent';
|
||||||
import EventEmitter from '../../lib/methods/helpers/events';
|
import EventEmitter from '../../lib/methods/helpers/events';
|
||||||
import Navigation from '../../lib/navigation/appNavigation';
|
import Navigation from '../../lib/navigation/appNavigation';
|
||||||
import { getActiveRoute } from '../../lib/methods/helpers/navigation';
|
import { getActiveRoute } from '../../lib/methods/helpers/navigation';
|
||||||
import { IApplicationState } from '../../definitions';
|
import { useAppSelector } from '../../lib/hooks';
|
||||||
import { IRoom } from '../../reducers/room';
|
|
||||||
|
|
||||||
export const INAPP_NOTIFICATION_EMITTER = 'NotificationInApp';
|
export const INAPP_NOTIFICATION_EMITTER = 'NotificationInApp';
|
||||||
|
|
||||||
const InAppNotification = memo(
|
const InAppNotification = memo(() => {
|
||||||
({ rooms, appState }: { rooms: IRoom['rooms']; appState: string }) => {
|
const { appState, subscribedRoom } = useAppSelector(state => ({
|
||||||
const show = (notification: INotifierComponent['notification']) => {
|
subscribedRoom: state.room.subscribedRoom,
|
||||||
if (appState !== 'foreground') {
|
appState: state.app.ready && state.app.foreground ? 'foreground' : 'background'
|
||||||
|
}));
|
||||||
|
|
||||||
|
const show = (notification: INotifierComponent['notification']) => {
|
||||||
|
if (appState !== 'foreground') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const { payload } = notification;
|
||||||
|
const state = Navigation.navigationRef.current?.getRootState();
|
||||||
|
const route = getActiveRoute(state);
|
||||||
|
if (payload.rid) {
|
||||||
|
if (payload.rid === subscribedRoom || route?.name === 'JitsiMeetView') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Notifier.showNotification({
|
||||||
const { payload } = notification;
|
showEasing: Easing.inOut(Easing.quad),
|
||||||
const state = Navigation.navigationRef.current?.getRootState();
|
Component: NotifierComponent,
|
||||||
const route = getActiveRoute(state);
|
componentProps: {
|
||||||
if (payload.rid) {
|
notification
|
||||||
if (rooms.includes(payload.rid) || route?.name === 'JitsiMeetView') {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
Notifier.showNotification({
|
});
|
||||||
showEasing: Easing.inOut(Easing.quad),
|
}
|
||||||
Component: NotifierComponent,
|
};
|
||||||
componentProps: {
|
|
||||||
notification
|
useEffect(() => {
|
||||||
}
|
const listener = EventEmitter.addEventListener(INAPP_NOTIFICATION_EMITTER, show);
|
||||||
});
|
return () => {
|
||||||
}
|
EventEmitter.removeListener(INAPP_NOTIFICATION_EMITTER, listener);
|
||||||
};
|
};
|
||||||
|
}, [subscribedRoom, appState]);
|
||||||
|
|
||||||
useEffect(() => {
|
return <NotifierRoot />;
|
||||||
const listener = EventEmitter.addEventListener(INAPP_NOTIFICATION_EMITTER, show);
|
|
||||||
return () => {
|
|
||||||
EventEmitter.removeListener(INAPP_NOTIFICATION_EMITTER, listener);
|
|
||||||
};
|
|
||||||
}, [rooms]);
|
|
||||||
|
|
||||||
return <NotifierRoot />;
|
|
||||||
},
|
|
||||||
(prevProps, nextProps) => dequal(prevProps.rooms, nextProps.rooms)
|
|
||||||
);
|
|
||||||
|
|
||||||
const mapStateToProps = (state: IApplicationState) => ({
|
|
||||||
rooms: state.room.rooms,
|
|
||||||
appState: state.app.ready && state.app.foreground ? 'foreground' : 'background'
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default connect(mapStateToProps)(InAppNotification);
|
export default InAppNotification;
|
||||||
|
|
|
@ -14,12 +14,12 @@ import { IEmoji, TAnyMessageModel } from '../../definitions';
|
||||||
import Touch from '../Touch';
|
import Touch from '../Touch';
|
||||||
|
|
||||||
export interface IHeader {
|
export interface IHeader {
|
||||||
handleReaction: (emoji: IEmoji, message: TAnyMessageModel) => void;
|
handleReaction: (emoji: IEmoji | null, message: TAnyMessageModel) => void;
|
||||||
message: TAnyMessageModel;
|
message: TAnyMessageModel;
|
||||||
isMasterDetail: boolean;
|
isMasterDetail: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type TOnReaction = ({ emoji }: { emoji: IEmoji }) => void;
|
type TOnReaction = ({ emoji }: { emoji?: IEmoji }) => void;
|
||||||
|
|
||||||
interface THeaderItem {
|
interface THeaderItem {
|
||||||
item: IEmoji;
|
item: IEmoji;
|
||||||
|
@ -94,8 +94,10 @@ const Header = React.memo(({ handleReaction, message, isMasterDetail }: IHeader)
|
||||||
const quantity = Math.trunc(size / (ITEM_SIZE + ITEM_MARGIN * 2) - 1);
|
const quantity = Math.trunc(size / (ITEM_SIZE + ITEM_MARGIN * 2) - 1);
|
||||||
|
|
||||||
const onReaction: TOnReaction = ({ emoji }) => {
|
const onReaction: TOnReaction = ({ emoji }) => {
|
||||||
handleReaction(emoji, message);
|
handleReaction(emoji || null, message);
|
||||||
addFrequentlyUsed(emoji);
|
if (emoji) {
|
||||||
|
addFrequentlyUsed(emoji);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const renderItem = ({ item }: { item: IEmoji }) => <HeaderItem item={item} onReaction={onReaction} theme={theme} />;
|
const renderItem = ({ item }: { item: IEmoji }) => <HeaderItem item={item} onReaction={onReaction} theme={theme} />;
|
||||||
|
|
|
@ -40,6 +40,7 @@ export interface IMessageActionsProps {
|
||||||
editMessagePermission?: string[];
|
editMessagePermission?: string[];
|
||||||
deleteMessagePermission?: string[];
|
deleteMessagePermission?: string[];
|
||||||
forceDeleteMessagePermission?: string[];
|
forceDeleteMessagePermission?: string[];
|
||||||
|
deleteOwnMessagePermission?: string[];
|
||||||
pinMessagePermission?: string[];
|
pinMessagePermission?: string[];
|
||||||
createDirectMessagePermission?: string[];
|
createDirectMessagePermission?: string[];
|
||||||
}
|
}
|
||||||
|
@ -71,6 +72,7 @@ const MessageActions = React.memo(
|
||||||
editMessagePermission,
|
editMessagePermission,
|
||||||
deleteMessagePermission,
|
deleteMessagePermission,
|
||||||
forceDeleteMessagePermission,
|
forceDeleteMessagePermission,
|
||||||
|
deleteOwnMessagePermission,
|
||||||
pinMessagePermission,
|
pinMessagePermission,
|
||||||
createDirectMessagePermission
|
createDirectMessagePermission
|
||||||
},
|
},
|
||||||
|
@ -80,19 +82,27 @@ const MessageActions = React.memo(
|
||||||
hasEditPermission: false,
|
hasEditPermission: false,
|
||||||
hasDeletePermission: false,
|
hasDeletePermission: false,
|
||||||
hasForceDeletePermission: false,
|
hasForceDeletePermission: false,
|
||||||
hasPinPermission: false
|
hasPinPermission: false,
|
||||||
|
hasDeleteOwnPermission: false
|
||||||
};
|
};
|
||||||
const { showActionSheet, hideActionSheet } = useActionSheet();
|
const { showActionSheet, hideActionSheet } = useActionSheet();
|
||||||
|
|
||||||
const getPermissions = async () => {
|
const getPermissions = async () => {
|
||||||
try {
|
try {
|
||||||
const permission = [editMessagePermission, deleteMessagePermission, forceDeleteMessagePermission, pinMessagePermission];
|
const permission = [
|
||||||
|
editMessagePermission,
|
||||||
|
deleteMessagePermission,
|
||||||
|
forceDeleteMessagePermission,
|
||||||
|
pinMessagePermission,
|
||||||
|
deleteOwnMessagePermission
|
||||||
|
];
|
||||||
const result = await hasPermission(permission, room.rid);
|
const result = await hasPermission(permission, room.rid);
|
||||||
permissions = {
|
permissions = {
|
||||||
hasEditPermission: result[0],
|
hasEditPermission: result[0],
|
||||||
hasDeletePermission: result[1],
|
hasDeletePermission: result[1],
|
||||||
hasForceDeletePermission: result[2],
|
hasForceDeletePermission: result[2],
|
||||||
hasPinPermission: result[3]
|
hasPinPermission: result[3],
|
||||||
|
hasDeleteOwnPermission: result[4]
|
||||||
};
|
};
|
||||||
} catch {
|
} catch {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
|
@ -134,7 +144,7 @@ const MessageActions = React.memo(
|
||||||
if (tmid === message.id) {
|
if (tmid === message.id) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const deleteOwn = isOwn(message);
|
const deleteOwn = isOwn(message) && permissions.hasDeleteOwnPermission;
|
||||||
if (!(permissions.hasDeletePermission || (Message_AllowDeleting && deleteOwn) || permissions.hasForceDeletePermission)) {
|
if (!(permissions.hasDeletePermission || (Message_AllowDeleting && deleteOwn) || permissions.hasForceDeletePermission)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -275,10 +285,10 @@ const MessageActions = React.memo(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleReaction: IHeader['handleReaction'] = (shortname, message) => {
|
const handleReaction: IHeader['handleReaction'] = (emoji, message) => {
|
||||||
logEvent(events.ROOM_MSG_ACTION_REACTION);
|
logEvent(events.ROOM_MSG_ACTION_REACTION);
|
||||||
if (shortname) {
|
if (emoji) {
|
||||||
onReactionPress(shortname, message.id);
|
onReactionPress(emoji, message.id);
|
||||||
} else {
|
} else {
|
||||||
setTimeout(() => reactionInit(message), ACTION_SHEET_ANIMATION_DURATION);
|
setTimeout(() => reactionInit(message), ACTION_SHEET_ANIMATION_DURATION);
|
||||||
}
|
}
|
||||||
|
@ -343,9 +353,10 @@ const MessageActions = React.memo(
|
||||||
|
|
||||||
const getOptions = (message: TAnyMessageModel) => {
|
const getOptions = (message: TAnyMessageModel) => {
|
||||||
const options: TActionSheetOptionsItem[] = [];
|
const options: TActionSheetOptionsItem[] = [];
|
||||||
|
const videoConfBlock = message.t === 'videoconf';
|
||||||
|
|
||||||
// Quote
|
// Quote
|
||||||
if (!isReadOnly) {
|
if (!isReadOnly && !videoConfBlock) {
|
||||||
options.push({
|
options.push({
|
||||||
title: I18n.t('Quote'),
|
title: I18n.t('Quote'),
|
||||||
icon: 'quote',
|
icon: 'quote',
|
||||||
|
@ -363,7 +374,7 @@ const MessageActions = React.memo(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reply in DM
|
// Reply in DM
|
||||||
if (room.t !== 'd' && room.t !== 'l' && createDirectMessagePermission) {
|
if (room.t !== 'd' && room.t !== 'l' && createDirectMessagePermission && !videoConfBlock) {
|
||||||
options.push({
|
options.push({
|
||||||
title: I18n.t('Reply_in_direct_message'),
|
title: I18n.t('Reply_in_direct_message'),
|
||||||
icon: 'arrow-back',
|
icon: 'arrow-back',
|
||||||
|
@ -386,11 +397,13 @@ const MessageActions = React.memo(
|
||||||
});
|
});
|
||||||
|
|
||||||
// Copy
|
// Copy
|
||||||
options.push({
|
if (!videoConfBlock) {
|
||||||
title: I18n.t('Copy'),
|
options.push({
|
||||||
icon: 'copy',
|
title: I18n.t('Copy'),
|
||||||
onPress: () => handleCopy(message)
|
icon: 'copy',
|
||||||
});
|
onPress: () => handleCopy(message)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Share
|
// Share
|
||||||
options.push({
|
options.push({
|
||||||
|
@ -400,7 +413,7 @@ const MessageActions = React.memo(
|
||||||
});
|
});
|
||||||
|
|
||||||
// Edit
|
// Edit
|
||||||
if (allowEdit(message)) {
|
if (allowEdit(message) && !videoConfBlock) {
|
||||||
options.push({
|
options.push({
|
||||||
title: I18n.t('Edit'),
|
title: I18n.t('Edit'),
|
||||||
icon: 'edit',
|
icon: 'edit',
|
||||||
|
@ -409,7 +422,7 @@ const MessageActions = React.memo(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pin
|
// Pin
|
||||||
if (Message_AllowPinning && permissions?.hasPinPermission) {
|
if (Message_AllowPinning && permissions?.hasPinPermission && !videoConfBlock) {
|
||||||
options.push({
|
options.push({
|
||||||
title: I18n.t(message.pinned ? 'Unpin' : 'Pin'),
|
title: I18n.t(message.pinned ? 'Unpin' : 'Pin'),
|
||||||
icon: 'pin',
|
icon: 'pin',
|
||||||
|
@ -418,7 +431,7 @@ const MessageActions = React.memo(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Star
|
// Star
|
||||||
if (Message_AllowStarring) {
|
if (Message_AllowStarring && !videoConfBlock) {
|
||||||
options.push({
|
options.push({
|
||||||
title: I18n.t(message.starred ? 'Unstar' : 'Star'),
|
title: I18n.t(message.starred ? 'Unstar' : 'Star'),
|
||||||
icon: message.starred ? 'star-filled' : 'star',
|
icon: message.starred ? 'star-filled' : 'star',
|
||||||
|
@ -505,6 +518,7 @@ const mapStateToProps = (state: IApplicationState) => ({
|
||||||
isMasterDetail: state.app.isMasterDetail,
|
isMasterDetail: state.app.isMasterDetail,
|
||||||
editMessagePermission: state.permissions['edit-message'],
|
editMessagePermission: state.permissions['edit-message'],
|
||||||
deleteMessagePermission: state.permissions['delete-message'],
|
deleteMessagePermission: state.permissions['delete-message'],
|
||||||
|
deleteOwnMessagePermission: state.permissions['delete-own-message'],
|
||||||
forceDeleteMessagePermission: state.permissions['force-delete-message'],
|
forceDeleteMessagePermission: state.permissions['force-delete-message'],
|
||||||
pinMessagePermission: state.permissions['pin-message'],
|
pinMessagePermission: state.permissions['pin-message'],
|
||||||
createDirectMessagePermission: state.permissions['create-d']
|
createDirectMessagePermission: state.permissions['create-d']
|
||||||
|
|
|
@ -237,7 +237,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
const { rid, tmid, navigation, sharing, usedCannedResponse, isMasterDetail } = this.props;
|
const { rid, tmid, navigation, sharing, usedCannedResponse } = this.props;
|
||||||
let msg;
|
let msg;
|
||||||
try {
|
try {
|
||||||
const threadsCollection = db.get('threads');
|
const threadsCollection = db.get('threads');
|
||||||
|
@ -272,7 +272,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
EventEmiter.addEventListener(KEY_COMMAND, this.handleCommands);
|
EventEmiter.addEventListener(KEY_COMMAND, this.handleCommands);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isMasterDetail && usedCannedResponse) {
|
if (usedCannedResponse) {
|
||||||
this.onChangeText(usedCannedResponse);
|
this.onChangeText(usedCannedResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,7 +302,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
if (usedCannedResponse !== nextProps.usedCannedResponse) {
|
if (usedCannedResponse !== nextProps.usedCannedResponse) {
|
||||||
this.onChangeText(nextProps.usedCannedResponse ?? '');
|
this.onChangeText(nextProps.usedCannedResponse ?? '');
|
||||||
}
|
}
|
||||||
if (sharing) {
|
if (sharing && !replying) {
|
||||||
this.setInput(nextProps.message.msg ?? '');
|
this.setInput(nextProps.message.msg ?? '');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -857,14 +857,21 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
openShareView = (attachments: any) => {
|
openShareView = (attachments: any) => {
|
||||||
const { message, replyCancel, replyWithMention } = this.props;
|
const { message, replyCancel, replyWithMention, replying } = this.props;
|
||||||
// Start a thread with an attachment
|
// Start a thread with an attachment
|
||||||
let value: TThreadModel | IMessage = this.thread;
|
let value: TThreadModel | IMessage = this.thread;
|
||||||
if (replyWithMention) {
|
if (replyWithMention) {
|
||||||
value = message;
|
value = message;
|
||||||
replyCancel();
|
replyCancel();
|
||||||
}
|
}
|
||||||
Navigation.navigate('ShareView', { room: this.room, thread: value, attachments });
|
Navigation.navigate('ShareView', {
|
||||||
|
room: this.room,
|
||||||
|
thread: value,
|
||||||
|
attachments,
|
||||||
|
replying,
|
||||||
|
replyingMessage: message,
|
||||||
|
closeReply: replyCancel
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
createDiscussion = () => {
|
createDiscussion = () => {
|
||||||
|
@ -1042,16 +1049,7 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
|
|
||||||
// Legacy reply or quote (quote is a reply without mention)
|
// Legacy reply or quote (quote is a reply without mention)
|
||||||
} else {
|
} else {
|
||||||
const { user, roomType } = this.props;
|
const msg = await this.formatReplyMessage(replyingMessage, message);
|
||||||
const permalink = await this.getPermalink(replyingMessage);
|
|
||||||
let msg = `[ ](${permalink}) `;
|
|
||||||
|
|
||||||
// if original message wasn't sent by current user and neither from a direct room
|
|
||||||
if (user.username !== replyingMessage?.u?.username && roomType !== 'd' && replyWithMention) {
|
|
||||||
msg += `@${replyingMessage?.u?.username} `;
|
|
||||||
}
|
|
||||||
|
|
||||||
msg = `${msg} ${message}`;
|
|
||||||
onSubmit(msg);
|
onSubmit(msg);
|
||||||
}
|
}
|
||||||
replyCancel();
|
replyCancel();
|
||||||
|
@ -1063,6 +1061,20 @@ class MessageBox extends Component<IMessageBoxProps, IMessageBoxState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
formatReplyMessage = async (replyingMessage: IMessage, message = '') => {
|
||||||
|
const { user, roomType, replyWithMention, serverVersion } = this.props;
|
||||||
|
const permalink = await this.getPermalink(replyingMessage);
|
||||||
|
let msg = `[ ](${permalink}) `;
|
||||||
|
|
||||||
|
// if original message wasn't sent by current user and neither from a direct room
|
||||||
|
if (user.username !== replyingMessage?.u?.username && roomType !== 'd' && replyWithMention) {
|
||||||
|
msg += `@${replyingMessage?.u?.username} `;
|
||||||
|
}
|
||||||
|
|
||||||
|
const connectionString = compareServerVersion(serverVersion, 'lowerThan', '5.0.0') ? ' ' : '\n';
|
||||||
|
return `${msg}${connectionString}${message}`;
|
||||||
|
};
|
||||||
|
|
||||||
updateMentions = (keyword: any, type: string) => {
|
updateMentions = (keyword: any, type: string) => {
|
||||||
if (type === MENTIONS_TRACKING_TYPE_USERS) {
|
if (type === MENTIONS_TRACKING_TYPE_USERS) {
|
||||||
this.getUsers(keyword);
|
this.getUsers(keyword);
|
||||||
|
|
|
@ -2,13 +2,13 @@ import React, { useEffect, useReducer, useRef } from 'react';
|
||||||
import { Subscription } from 'rxjs';
|
import { Subscription } from 'rxjs';
|
||||||
|
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { useAppSelector } from '../../lib/hooks';
|
|
||||||
import { getUserPresence } from '../../lib/methods';
|
import { getUserPresence } from '../../lib/methods';
|
||||||
import { isGroupChat } from '../../lib/methods/helpers';
|
import { isGroupChat } from '../../lib/methods/helpers';
|
||||||
import { formatDate } from '../../lib/methods/helpers/room';
|
import { formatDate } from '../../lib/methods/helpers/room';
|
||||||
import { IRoomItemContainerProps } from './interfaces';
|
import { IRoomItemContainerProps } from './interfaces';
|
||||||
import RoomItem from './RoomItem';
|
import RoomItem from './RoomItem';
|
||||||
import { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from './styles';
|
import { ROW_HEIGHT, ROW_HEIGHT_CONDENSED } from './styles';
|
||||||
|
import { useUserStatus } from './useUserStatus';
|
||||||
|
|
||||||
export { ROW_HEIGHT, ROW_HEIGHT_CONDENSED };
|
export { ROW_HEIGHT, ROW_HEIGHT_CONDENSED };
|
||||||
|
|
||||||
|
@ -42,11 +42,11 @@ const RoomItemContainer = React.memo(
|
||||||
const isRead = getIsRead(item);
|
const isRead = getIsRead(item);
|
||||||
const date = item.roomUpdatedAt && formatDate(item.roomUpdatedAt);
|
const date = item.roomUpdatedAt && formatDate(item.roomUpdatedAt);
|
||||||
const alert = item.alert || item.tunread?.length;
|
const alert = item.alert || item.tunread?.length;
|
||||||
const connected = useAppSelector(state => state.meteor.connected);
|
|
||||||
const userStatus = useAppSelector(state => state.activeUsers[id || '']?.status);
|
|
||||||
const [_, forceUpdate] = useReducer(x => x + 1, 1);
|
const [_, forceUpdate] = useReducer(x => x + 1, 1);
|
||||||
const roomSubscription = useRef<Subscription | null>(null);
|
const roomSubscription = useRef<Subscription | null>(null);
|
||||||
|
|
||||||
|
const { connected, status } = useUserStatus(item.t, item?.visitor?.status, id);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const init = () => {
|
const init = () => {
|
||||||
if (item?.observe) {
|
if (item?.observe) {
|
||||||
|
@ -85,8 +85,6 @@ const RoomItemContainer = React.memo(
|
||||||
accessibilityLabel = `, ${I18n.t('last_message')} ${date}`;
|
accessibilityLabel = `, ${I18n.t('last_message')} ${date}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
const status = item.t === 'l' ? item.visitor?.status || item.v?.status : userStatus;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RoomItem
|
<RoomItem
|
||||||
name={name}
|
name={name}
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
import { TUserStatus } from '../../definitions';
|
||||||
|
import { useAppSelector } from '../../lib/hooks';
|
||||||
|
import { RoomTypes } from '../../lib/methods';
|
||||||
|
|
||||||
|
export const useUserStatus = (
|
||||||
|
type: RoomTypes,
|
||||||
|
liveChatStatus?: TUserStatus,
|
||||||
|
id?: string
|
||||||
|
): { connected: boolean; status: TUserStatus } => {
|
||||||
|
const connected = useAppSelector(state => state.meteor.connected);
|
||||||
|
const userStatus = useAppSelector(state => state.activeUsers[id || '']?.status);
|
||||||
|
let status = 'loading';
|
||||||
|
if (connected) {
|
||||||
|
if (type === 'd') {
|
||||||
|
status = userStatus || 'loading';
|
||||||
|
} else if (type === 'l' && liveChatStatus) {
|
||||||
|
status = liveChatStatus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
connected,
|
||||||
|
status: status as TUserStatus
|
||||||
|
};
|
||||||
|
};
|
|
@ -19,8 +19,8 @@ const styles = StyleSheet.create({
|
||||||
input: {
|
input: {
|
||||||
height: 48,
|
height: 48,
|
||||||
paddingLeft: 16,
|
paddingLeft: 16,
|
||||||
borderWidth: 2,
|
borderWidth: 1,
|
||||||
borderRadius: 2,
|
borderRadius: 4,
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
flexDirection: 'row'
|
flexDirection: 'row'
|
||||||
},
|
},
|
||||||
|
|
|
@ -19,8 +19,8 @@ const styles = StyleSheet.create({
|
||||||
viewContainer: {
|
viewContainer: {
|
||||||
marginBottom: 16,
|
marginBottom: 16,
|
||||||
paddingHorizontal: 16,
|
paddingHorizontal: 16,
|
||||||
borderWidth: 2,
|
borderWidth: 1,
|
||||||
borderRadius: 2,
|
borderRadius: 4,
|
||||||
justifyContent: 'center'
|
justifyContent: 'center'
|
||||||
},
|
},
|
||||||
pickerText: {
|
pickerText: {
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { Text, View } from 'react-native';
|
||||||
|
import Touchable from 'react-native-platform-touchable';
|
||||||
|
|
||||||
|
import i18n from '../../../../i18n';
|
||||||
|
import { getSubscriptionByRoomId } from '../../../../lib/database/services/Subscription';
|
||||||
|
import { useAppSelector } from '../../../../lib/hooks';
|
||||||
|
import { getRoomAvatar, getUidDirectMessage } from '../../../../lib/methods/helpers';
|
||||||
|
import { videoConfStartAndJoin } from '../../../../lib/methods/videoConf';
|
||||||
|
import { useTheme } from '../../../../theme';
|
||||||
|
import { useActionSheet } from '../../../ActionSheet';
|
||||||
|
import AvatarContainer from '../../../Avatar';
|
||||||
|
import Button from '../../../Button';
|
||||||
|
import { CustomIcon } from '../../../CustomIcon';
|
||||||
|
import { BUTTON_HIT_SLOP } from '../../../message/utils';
|
||||||
|
import StatusContainer from '../../../Status';
|
||||||
|
import useStyle from './styles';
|
||||||
|
|
||||||
|
export default function CallAgainActionSheet({ rid }: { rid: string }): React.ReactElement {
|
||||||
|
const style = useStyle();
|
||||||
|
const { colors } = useTheme();
|
||||||
|
const [user, setUser] = useState({ username: '', avatar: '', uid: '', rid: '' });
|
||||||
|
const [phone, setPhone] = useState(true);
|
||||||
|
const [camera, setCamera] = useState(false);
|
||||||
|
const username = useAppSelector(state => state.login.user.username);
|
||||||
|
|
||||||
|
const { hideActionSheet } = useActionSheet();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
(async () => {
|
||||||
|
const room = await getSubscriptionByRoomId(rid);
|
||||||
|
const uid = (await getUidDirectMessage(room)) as string;
|
||||||
|
const avt = getRoomAvatar(room);
|
||||||
|
setUser({ uid, username: room?.name || '', avatar: avt, rid: room?.id || '' });
|
||||||
|
})();
|
||||||
|
}, [rid]);
|
||||||
|
|
||||||
|
const handleColor = (enabled: boolean) => (enabled ? colors.conferenceCallEnabledIcon : colors.conferenceCallDisabledIcon);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={style.actionSheetContainer}>
|
||||||
|
<View style={style.actionSheetHeader}>
|
||||||
|
<Text style={style.actionSheetHeaderTitle}>{i18n.t('Start_a_call')}</Text>
|
||||||
|
<View style={style.actionSheetHeaderButtons}>
|
||||||
|
<Touchable
|
||||||
|
onPress={() => setCamera(!camera)}
|
||||||
|
style={[style.iconCallContainer, camera && style.enabledBackground, { marginRight: 6 }]}
|
||||||
|
hitSlop={BUTTON_HIT_SLOP}
|
||||||
|
>
|
||||||
|
<CustomIcon name={camera ? 'camera' : 'camera-disabled'} size={16} color={handleColor(camera)} />
|
||||||
|
</Touchable>
|
||||||
|
<Touchable
|
||||||
|
onPress={() => setPhone(!phone)}
|
||||||
|
style={[style.iconCallContainer, phone && style.enabledBackground]}
|
||||||
|
hitSlop={BUTTON_HIT_SLOP}
|
||||||
|
>
|
||||||
|
<CustomIcon name={phone ? 'microphone' : 'microphone-disabled'} size={16} color={handleColor(phone)} />
|
||||||
|
</Touchable>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
<View style={style.actionSheetUsernameContainer}>
|
||||||
|
<AvatarContainer text={user.avatar} size={36} />
|
||||||
|
<StatusContainer size={16} id={user.uid} style={{ marginLeft: 8, marginRight: 6 }} />
|
||||||
|
<Text style={style.actionSheetUsername}>{user.username}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={style.actionSheetPhotoContainer}>
|
||||||
|
<AvatarContainer size={62} text={username} />
|
||||||
|
</View>
|
||||||
|
<Button
|
||||||
|
onPress={() => {
|
||||||
|
hideActionSheet();
|
||||||
|
setTimeout(() => {
|
||||||
|
videoConfStartAndJoin(user.rid, camera);
|
||||||
|
}, 100);
|
||||||
|
}}
|
||||||
|
title={i18n.t('Call')}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Text, View } from 'react-native';
|
||||||
|
|
||||||
|
import i18n from '../../../../i18n';
|
||||||
|
import useStyle from './styles';
|
||||||
|
import AvatarContainer from '../../../Avatar';
|
||||||
|
|
||||||
|
const MAX_USERS = 3;
|
||||||
|
|
||||||
|
export type TCallUsers = { _id: string; username: string; name: string; avatarETag: string }[];
|
||||||
|
|
||||||
|
export const CallParticipants = ({ users }: { users: TCallUsers }): React.ReactElement => {
|
||||||
|
const style = useStyle();
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
{users.map(({ username }, index) =>
|
||||||
|
index < MAX_USERS ? <AvatarContainer style={{ marginRight: 4 }} key={index} size={28} text={username} /> : null
|
||||||
|
)}
|
||||||
|
{users.length > MAX_USERS ? (
|
||||||
|
<View style={style.plusUsers}>
|
||||||
|
<Text style={style.plusUsersText}>{users.length > 9 ? '+9' : `+${users.length}`}</Text>
|
||||||
|
</View>
|
||||||
|
) : null}
|
||||||
|
<Text style={style.joined}>{i18n.t('Joined')}</Text>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,55 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { View, Text } from 'react-native';
|
||||||
|
|
||||||
|
import i18n from '../../../../i18n';
|
||||||
|
import { useTheme } from '../../../../theme';
|
||||||
|
import { CustomIcon, TIconsName } from '../../../CustomIcon';
|
||||||
|
import useStyle from './styles';
|
||||||
|
|
||||||
|
type VideoConfMessageIconProps = {
|
||||||
|
variant: 'ended' | 'incoming' | 'outgoing';
|
||||||
|
children: React.ReactElement | React.ReactElement[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const VideoConferenceBaseContainer = ({ variant, children }: VideoConfMessageIconProps): React.ReactElement => {
|
||||||
|
const { colors } = useTheme();
|
||||||
|
const style = useStyle();
|
||||||
|
|
||||||
|
const iconStyle: { [key: string]: { icon: TIconsName; color: string; backgroundColor: string; label: string } } = {
|
||||||
|
ended: {
|
||||||
|
icon: 'phone-end',
|
||||||
|
color: colors.conferenceCallEndedPhoneIcon,
|
||||||
|
backgroundColor: colors.conferenceCallEndedPhoneBackground,
|
||||||
|
label: i18n.t('Call_ended')
|
||||||
|
},
|
||||||
|
incoming: {
|
||||||
|
icon: 'phone-in',
|
||||||
|
color: colors.conferenceCallIncomingPhoneIcon,
|
||||||
|
backgroundColor: colors.conferenceCallIncomingPhoneBackground,
|
||||||
|
label: i18n.t('Calling')
|
||||||
|
},
|
||||||
|
outgoing: {
|
||||||
|
icon: 'phone',
|
||||||
|
color: colors.conferenceCallOngoingPhoneIcon,
|
||||||
|
backgroundColor: colors.conferenceCallOngoingPhoneBackground,
|
||||||
|
label: i18n.t('Call_ongoing')
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<View style={style.container}>
|
||||||
|
<View style={style.callInfoContainer}>
|
||||||
|
<View
|
||||||
|
style={{
|
||||||
|
...style.iconContainer,
|
||||||
|
backgroundColor: iconStyle[variant].backgroundColor
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<CustomIcon name={iconStyle[variant].icon} size={variant === 'incoming' ? 16 : 24} color={iconStyle[variant].color} />
|
||||||
|
</View>
|
||||||
|
<Text style={style.infoContainerText}>{iconStyle[variant].label}</Text>
|
||||||
|
</View>
|
||||||
|
<View style={style.callToActionContainer}>{children}</View>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
|
@ -0,0 +1,24 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Text } from 'react-native';
|
||||||
|
import Touchable from 'react-native-platform-touchable';
|
||||||
|
|
||||||
|
import i18n from '../../../../i18n';
|
||||||
|
import { useVideoConf } from '../../../../lib/hooks/useVideoConf';
|
||||||
|
import useStyle from './styles';
|
||||||
|
import { VideoConferenceBaseContainer } from './VideoConferenceBaseContainer';
|
||||||
|
|
||||||
|
const VideoConferenceDirect = React.memo(({ blockId }: { blockId: string }) => {
|
||||||
|
const style = useStyle();
|
||||||
|
const { joinCall } = useVideoConf();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<VideoConferenceBaseContainer variant='incoming'>
|
||||||
|
<Touchable style={style.callToActionButton} onPress={() => joinCall(blockId)}>
|
||||||
|
<Text style={style.callToActionButtonText}>{i18n.t('Join')}</Text>
|
||||||
|
</Touchable>
|
||||||
|
<Text style={style.callBack}>{i18n.t('Waiting_for_answer')}</Text>
|
||||||
|
</VideoConferenceBaseContainer>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
export default VideoConferenceDirect;
|
|
@ -0,0 +1,64 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Text } from 'react-native';
|
||||||
|
import Touchable from 'react-native-platform-touchable';
|
||||||
|
|
||||||
|
import { IUser } from '../../../../definitions';
|
||||||
|
import { VideoConferenceType } from '../../../../definitions/IVideoConference';
|
||||||
|
import i18n from '../../../../i18n';
|
||||||
|
import { useAppSelector } from '../../../../lib/hooks';
|
||||||
|
import { useSnaps } from '../../../../lib/hooks/useSnaps';
|
||||||
|
import { useActionSheet } from '../../../ActionSheet';
|
||||||
|
import CallAgainActionSheet from './CallAgainActionSheet';
|
||||||
|
import { CallParticipants, TCallUsers } from './CallParticipants';
|
||||||
|
import useStyle from './styles';
|
||||||
|
import { VideoConferenceBaseContainer } from './VideoConferenceBaseContainer';
|
||||||
|
|
||||||
|
export default function VideoConferenceEnded({
|
||||||
|
users,
|
||||||
|
type,
|
||||||
|
createdBy,
|
||||||
|
rid
|
||||||
|
}: {
|
||||||
|
users: TCallUsers;
|
||||||
|
type: VideoConferenceType;
|
||||||
|
createdBy: Pick<IUser, '_id' | 'username' | 'name'>;
|
||||||
|
rid: string;
|
||||||
|
}): React.ReactElement {
|
||||||
|
const style = useStyle();
|
||||||
|
const username = useAppSelector(state => state.login.user.username);
|
||||||
|
const { showActionSheet } = useActionSheet();
|
||||||
|
const snaps = useSnaps([1250]);
|
||||||
|
|
||||||
|
const onlyAuthorOnCall = users.length === 1 && users.some(user => user.username === createdBy.username);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<VideoConferenceBaseContainer variant='ended'>
|
||||||
|
{type === 'direct' ? (
|
||||||
|
<>
|
||||||
|
<Touchable
|
||||||
|
style={style.callToActionCallBack}
|
||||||
|
onPress={() =>
|
||||||
|
showActionSheet({
|
||||||
|
children: <CallAgainActionSheet rid={rid} />,
|
||||||
|
snaps
|
||||||
|
})
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Text style={style.callToActionCallBackText}>
|
||||||
|
{createdBy.username === username ? i18n.t('Call_back') : i18n.t('Call_again')}
|
||||||
|
</Text>
|
||||||
|
</Touchable>
|
||||||
|
<Text style={style.callBack}>{i18n.t('Call_was_not_answered')}</Text>
|
||||||
|
</>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{users.length && !onlyAuthorOnCall ? (
|
||||||
|
<CallParticipants users={users} />
|
||||||
|
) : (
|
||||||
|
<Text style={style.notAnswered}>{i18n.t('Call_was_not_answered')}</Text>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</VideoConferenceBaseContainer>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { Text } from 'react-native';
|
||||||
|
import Touchable from 'react-native-platform-touchable';
|
||||||
|
|
||||||
|
import i18n from '../../../../i18n';
|
||||||
|
import { useVideoConf } from '../../../../lib/hooks/useVideoConf';
|
||||||
|
import { CallParticipants, TCallUsers } from './CallParticipants';
|
||||||
|
import useStyle from './styles';
|
||||||
|
import { VideoConferenceBaseContainer } from './VideoConferenceBaseContainer';
|
||||||
|
|
||||||
|
export default function VideoConferenceOutgoing({ users, blockId }: { users: TCallUsers; blockId: string }): React.ReactElement {
|
||||||
|
const style = useStyle();
|
||||||
|
const { joinCall } = useVideoConf();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<VideoConferenceBaseContainer variant='outgoing'>
|
||||||
|
<Touchable style={style.callToActionButton} onPress={() => joinCall(blockId)}>
|
||||||
|
<Text style={style.callToActionButtonText}>{i18n.t('Join')}</Text>
|
||||||
|
</Touchable>
|
||||||
|
<CallParticipants users={users} />
|
||||||
|
</VideoConferenceBaseContainer>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
import React from 'react';
|
||||||
|
import SkeletonPlaceholder from 'react-native-skeleton-placeholder';
|
||||||
|
|
||||||
|
import { useTheme } from '../../../../theme';
|
||||||
|
|
||||||
|
export default function VideoConferenceSkeletonLoading(): React.ReactElement {
|
||||||
|
const { colors } = useTheme();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SkeletonPlaceholder backgroundColor={colors.conferenceCallBackground}>
|
||||||
|
<SkeletonPlaceholder.Item borderWidth={1} borderColor={colors.conferenceCallBorder} borderRadius={4} marginTop={8}>
|
||||||
|
<SkeletonPlaceholder.Item alignItems={'center'} flexDirection='row' marginTop={16} marginLeft={16}>
|
||||||
|
<SkeletonPlaceholder.Item width={28} height={26} />
|
||||||
|
<SkeletonPlaceholder.Item width={75} height={16} marginLeft={8} borderRadius={0} />
|
||||||
|
</SkeletonPlaceholder.Item>
|
||||||
|
<SkeletonPlaceholder.Item
|
||||||
|
width={'100%'}
|
||||||
|
height={48}
|
||||||
|
marginTop={16}
|
||||||
|
borderBottomLeftRadius={4}
|
||||||
|
borderBottomRightRadius={4}
|
||||||
|
borderTopLeftRadius={0}
|
||||||
|
borderTopRightRadius={0}
|
||||||
|
/>
|
||||||
|
</SkeletonPlaceholder.Item>
|
||||||
|
</SkeletonPlaceholder>
|
||||||
|
);
|
||||||
|
}
|
|
@ -0,0 +1,126 @@
|
||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
import { useTheme } from '../../../../theme';
|
||||||
|
import sharedStyles from '../../../../views/Styles';
|
||||||
|
|
||||||
|
export default function useStyle() {
|
||||||
|
const { colors } = useTheme();
|
||||||
|
return StyleSheet.create({
|
||||||
|
container: { height: 108, flex: 1, borderWidth: 1, borderRadius: 4, marginTop: 8, borderColor: colors.conferenceCallBorder },
|
||||||
|
callInfoContainer: { flex: 1, alignItems: 'center', paddingLeft: 16, flexDirection: 'row' },
|
||||||
|
infoContainerText: {
|
||||||
|
fontSize: 12,
|
||||||
|
marginLeft: 8,
|
||||||
|
...sharedStyles.textBold,
|
||||||
|
color: colors.auxiliaryTintColor
|
||||||
|
},
|
||||||
|
iconContainer: {
|
||||||
|
width: 28,
|
||||||
|
height: 28,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
borderRadius: 4
|
||||||
|
},
|
||||||
|
callToActionContainer: {
|
||||||
|
height: 48,
|
||||||
|
backgroundColor: colors.conferenceCallBackground,
|
||||||
|
flexDirection: 'row',
|
||||||
|
alignItems: 'center',
|
||||||
|
paddingLeft: 16
|
||||||
|
},
|
||||||
|
callToActionButtonText: {
|
||||||
|
fontSize: 12,
|
||||||
|
...sharedStyles.textSemibold,
|
||||||
|
color: colors.buttonText
|
||||||
|
},
|
||||||
|
callToActionCallBackText: {
|
||||||
|
fontSize: 12,
|
||||||
|
...sharedStyles.textSemibold,
|
||||||
|
color: colors.conferenceCallCallBackText
|
||||||
|
},
|
||||||
|
callToActionButton: {
|
||||||
|
backgroundColor: colors.tintColor,
|
||||||
|
minWidth: 50,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
height: 32,
|
||||||
|
borderRadius: 4,
|
||||||
|
marginRight: 8,
|
||||||
|
paddingHorizontal: 8
|
||||||
|
},
|
||||||
|
joined: {
|
||||||
|
fontSize: 12,
|
||||||
|
...sharedStyles.textRegular,
|
||||||
|
color: colors.passcodeSecondary,
|
||||||
|
marginLeft: 8
|
||||||
|
},
|
||||||
|
plusUsers: {
|
||||||
|
width: 28,
|
||||||
|
height: 28,
|
||||||
|
backgroundColor: colors.conferenceCallPlusUsersButton,
|
||||||
|
borderRadius: 4,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center'
|
||||||
|
},
|
||||||
|
plusUsersText: {
|
||||||
|
fontSize: 14,
|
||||||
|
...sharedStyles.textSemibold,
|
||||||
|
color: colors.conferenceCallPlusUsersText,
|
||||||
|
alignSelf: 'center'
|
||||||
|
},
|
||||||
|
callBack: {
|
||||||
|
fontSize: 12,
|
||||||
|
...sharedStyles.textRegular,
|
||||||
|
color: colors.passcodeSecondary
|
||||||
|
},
|
||||||
|
callToActionCallBack: {
|
||||||
|
backgroundColor: colors.conferenceCallPlusUsersButton,
|
||||||
|
minWidth: 50,
|
||||||
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
height: 32,
|
||||||
|
borderRadius: 4,
|
||||||
|
marginRight: 8,
|
||||||
|
paddingHorizontal: 8
|
||||||
|
},
|
||||||
|
notAnswered: {
|
||||||
|
fontSize: 12,
|
||||||
|
...sharedStyles.textRegular,
|
||||||
|
color: colors.passcodeSecondary
|
||||||
|
},
|
||||||
|
actionSheetContainer: {
|
||||||
|
paddingHorizontal: 24,
|
||||||
|
flex: 1
|
||||||
|
},
|
||||||
|
actionSheetHeaderTitle: {
|
||||||
|
fontSize: 14,
|
||||||
|
...sharedStyles.textBold,
|
||||||
|
color: colors.passcodePrimary
|
||||||
|
},
|
||||||
|
actionSheetUsername: {
|
||||||
|
fontSize: 16,
|
||||||
|
...sharedStyles.textBold,
|
||||||
|
color: colors.passcodePrimary
|
||||||
|
},
|
||||||
|
enabledBackground: {
|
||||||
|
backgroundColor: colors.conferenceCallEnabledIconBackground
|
||||||
|
},
|
||||||
|
iconCallContainer: {
|
||||||
|
padding: 6,
|
||||||
|
borderRadius: 4
|
||||||
|
},
|
||||||
|
actionSheetHeader: { flexDirection: 'row', alignItems: 'center' },
|
||||||
|
actionSheetHeaderButtons: { flex: 1, alignItems: 'center', flexDirection: 'row', justifyContent: 'flex-end' },
|
||||||
|
actionSheetUsernameContainer: { flexDirection: 'row', paddingTop: 8, alignItems: 'center' },
|
||||||
|
actionSheetPhotoContainer: {
|
||||||
|
height: 220,
|
||||||
|
width: 148,
|
||||||
|
backgroundColor: colors.conferenceCallPhotoBackground,
|
||||||
|
borderRadius: 8,
|
||||||
|
margin: 24,
|
||||||
|
alignSelf: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import { useEndpointData } from '../../../lib/hooks/useEndpointData';
|
||||||
|
import VideoConferenceDirect from './components/VideoConferenceDirect';
|
||||||
|
import VideoConferenceEnded from './components/VideoConferenceEnded';
|
||||||
|
import VideoConferenceOutgoing from './components/VideoConferenceOutgoing';
|
||||||
|
import VideoConferenceSkeletonLoading from './components/VideoConferenceSkeletonLoading';
|
||||||
|
|
||||||
|
export default function VideoConferenceBlock({ callId, blockId }: { callId: string; blockId: string }): React.ReactElement {
|
||||||
|
const { result } = useEndpointData('video-conference.info', { callId });
|
||||||
|
|
||||||
|
if (result?.success) {
|
||||||
|
const { users, type, status, createdBy, rid } = result;
|
||||||
|
|
||||||
|
if ('endedAt' in result) return <VideoConferenceEnded createdBy={createdBy} rid={rid} type={type} users={users} />;
|
||||||
|
|
||||||
|
if (type === 'direct' && status === 0) return <VideoConferenceDirect blockId={blockId} />;
|
||||||
|
|
||||||
|
return <VideoConferenceOutgoing blockId={blockId} users={users} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <VideoConferenceSkeletonLoading />;
|
||||||
|
}
|
|
@ -29,6 +29,7 @@ import { DatePicker } from './DatePicker';
|
||||||
import { Overflow } from './Overflow';
|
import { Overflow } from './Overflow';
|
||||||
import { ThemeContext } from '../../theme';
|
import { ThemeContext } from '../../theme';
|
||||||
import { IActions, IButton, IElement, IInputIndex, IParser, ISection } from './interfaces';
|
import { IActions, IButton, IElement, IInputIndex, IParser, ISection } from './interfaces';
|
||||||
|
import VideoConferenceBlock from './VideoConferenceBlock';
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
input: {
|
input: {
|
||||||
|
@ -149,6 +150,10 @@ class MessageParser extends UiKitParserMessage<React.ReactElement> {
|
||||||
const [{ loading, value }, action] = useBlockContext(element, context);
|
const [{ loading, value }, action] = useBlockContext(element, context);
|
||||||
return <MultiSelect {...element} value={value} onChange={action} context={context} loading={loading} />;
|
return <MultiSelect {...element} value={value} onChange={action} context={context} loading={loading} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
video_conf(element: IElement & { callId: string }) {
|
||||||
|
return <VideoConferenceBlock callId={element.callId} blockId={element.blockId!} />;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// plain_text and mrkdwn functions are created in MessageParser and the ModalParser's constructor use the same functions
|
// plain_text and mrkdwn functions are created in MessageParser and the ModalParser's constructor use the same functions
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
/* eslint-disable no-shadow */
|
/* eslint-disable no-shadow */
|
||||||
import React, { useContext, useState } from 'react';
|
|
||||||
import { BlockContext } from '@rocket.chat/ui-kit';
|
import { BlockContext } from '@rocket.chat/ui-kit';
|
||||||
|
import React, { useContext, useState } from 'react';
|
||||||
|
|
||||||
|
import { useVideoConf } from '../../lib/hooks/useVideoConf';
|
||||||
import { IText } from './interfaces';
|
import { IText } from './interfaces';
|
||||||
import { videoConfJoin } from '../../lib/methods/videoConf';
|
|
||||||
import { TActionSheetOptionsItem, useActionSheet } from '../ActionSheet';
|
|
||||||
import i18n from '../../i18n';
|
|
||||||
|
|
||||||
export const textParser = ([{ text }]: IText[]) => text;
|
export const textParser = ([{ text }]: IText[]) => text;
|
||||||
|
|
||||||
|
@ -42,7 +40,7 @@ export const useBlockContext = ({ blockId, actionId, appId, initialValue }: IUse
|
||||||
const { action, appId: appIdFromContext, viewId, state, language, errors, values = {} } = useContext(KitContext);
|
const { action, appId: appIdFromContext, viewId, state, language, errors, values = {} } = useContext(KitContext);
|
||||||
const { value = initialValue } = values[actionId] || {};
|
const { value = initialValue } = values[actionId] || {};
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const { showActionSheet } = useActionSheet();
|
const { joinCall } = useVideoConf();
|
||||||
|
|
||||||
const error = errors && actionId && errors[actionId];
|
const error = errors && actionId && errors[actionId];
|
||||||
|
|
||||||
|
@ -60,20 +58,7 @@ export const useBlockContext = ({ blockId, actionId, appId, initialValue }: IUse
|
||||||
try {
|
try {
|
||||||
if (appId === 'videoconf-core' && blockId) {
|
if (appId === 'videoconf-core' && blockId) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
const options: TActionSheetOptionsItem[] = [
|
return joinCall(blockId);
|
||||||
{
|
|
||||||
title: i18n.t('Video_call'),
|
|
||||||
icon: 'camera',
|
|
||||||
onPress: () => videoConfJoin(blockId, true)
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: i18n.t('Voice_call'),
|
|
||||||
icon: 'microphone',
|
|
||||||
onPress: () => videoConfJoin(blockId, false)
|
|
||||||
}
|
|
||||||
];
|
|
||||||
showActionSheet({ options });
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
await action({
|
await action({
|
||||||
blockId,
|
blockId,
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
import React from 'react';
|
||||||
|
import { View, StyleSheet, Text, ViewStyle } from 'react-native';
|
||||||
|
|
||||||
|
import sharedStyles from '../views/Styles';
|
||||||
|
import { useTheme } from '../theme';
|
||||||
|
import openLink from '../lib/methods/helpers/openLink';
|
||||||
|
import { useAppSelector } from '../lib/hooks';
|
||||||
|
import I18n from '../i18n';
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
bottomContainer: {
|
||||||
|
flexDirection: 'column',
|
||||||
|
alignItems: 'center',
|
||||||
|
marginBottom: 32,
|
||||||
|
marginHorizontal: 30
|
||||||
|
},
|
||||||
|
bottomContainerText: {
|
||||||
|
...sharedStyles.textRegular,
|
||||||
|
fontSize: 13
|
||||||
|
},
|
||||||
|
bottomContainerTextBold: {
|
||||||
|
...sharedStyles.textSemibold,
|
||||||
|
fontSize: 13
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const UGCRules = ({ styleContainer }: { styleContainer?: ViewStyle }) => {
|
||||||
|
const { colors, theme } = useTheme();
|
||||||
|
const { server } = useAppSelector(state => ({
|
||||||
|
server: state.server.server
|
||||||
|
}));
|
||||||
|
|
||||||
|
const openContract = (route: string) => {
|
||||||
|
if (!server) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
openLink(`${server}/${route}`, theme);
|
||||||
|
};
|
||||||
|
return (
|
||||||
|
<View style={[styles.bottomContainer, styleContainer]}>
|
||||||
|
<Text style={[styles.bottomContainerText, { color: colors.auxiliaryText }]}>
|
||||||
|
{`${I18n.t('Onboarding_agree_terms')}\n`}
|
||||||
|
<Text
|
||||||
|
style={[styles.bottomContainerTextBold, { color: colors.actionTintColor }]}
|
||||||
|
onPress={() => openContract('terms-of-service')}
|
||||||
|
>
|
||||||
|
{I18n.t('Terms_of_Service')}
|
||||||
|
</Text>{' '}
|
||||||
|
{I18n.t('and')}
|
||||||
|
<Text
|
||||||
|
style={[styles.bottomContainerTextBold, { color: colors.actionTintColor }]}
|
||||||
|
onPress={() => openContract('privacy-policy')}
|
||||||
|
>
|
||||||
|
{' '}
|
||||||
|
{I18n.t('Privacy_Policy')}
|
||||||
|
</Text>
|
||||||
|
</Text>
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default UGCRules;
|
|
@ -1,14 +1,11 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { StyleProp, Text, TextStyle } from 'react-native';
|
import { StyleProp, Text, TextStyle } from 'react-native';
|
||||||
import { useNavigation } from '@react-navigation/native';
|
|
||||||
import { StackNavigationProp } from '@react-navigation/stack';
|
|
||||||
|
|
||||||
import { themes } from '../../lib/constants';
|
import { themes } from '../../lib/constants';
|
||||||
import { useTheme } from '../../theme';
|
import { useTheme } from '../../theme';
|
||||||
import { IUserChannel } from './interfaces';
|
import { IUserChannel } from './interfaces';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import { getSubscriptionByRoomId } from '../../lib/database/services/Subscription';
|
import { getSubscriptionByRoomId } from '../../lib/database/services/Subscription';
|
||||||
import { ChatsStackParamList } from '../../stacks/types';
|
|
||||||
import { useAppSelector } from '../../lib/hooks';
|
import { useAppSelector } from '../../lib/hooks';
|
||||||
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
import { goRoom } from '../../lib/methods/helpers/goRoom';
|
||||||
|
|
||||||
|
@ -22,7 +19,6 @@ interface IHashtag {
|
||||||
const Hashtag = React.memo(({ hashtag, channels, navToRoomInfo, style = [] }: IHashtag) => {
|
const Hashtag = React.memo(({ hashtag, channels, navToRoomInfo, style = [] }: IHashtag) => {
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
|
const isMasterDetail = useAppSelector(state => state.app.isMasterDetail);
|
||||||
const navigation = useNavigation<StackNavigationProp<ChatsStackParamList, 'RoomView'>>();
|
|
||||||
|
|
||||||
const handlePress = async () => {
|
const handlePress = async () => {
|
||||||
const index = channels?.findIndex(channel => channel.name === hashtag);
|
const index = channels?.findIndex(channel => channel.name === hashtag);
|
||||||
|
@ -33,7 +29,7 @@ const Hashtag = React.memo(({ hashtag, channels, navToRoomInfo, style = [] }: IH
|
||||||
};
|
};
|
||||||
const room = navParam.rid && (await getSubscriptionByRoomId(navParam.rid));
|
const room = navParam.rid && (await getSubscriptionByRoomId(navParam.rid));
|
||||||
if (room) {
|
if (room) {
|
||||||
goRoom({ item: room, isMasterDetail, navigationMethod: isMasterDetail ? navigation.replace : navigation.push });
|
goRoom({ item: room, isMasterDetail });
|
||||||
} else {
|
} else {
|
||||||
navToRoomInfo(navParam);
|
navToRoomInfo(navParam);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,7 @@ interface IMarkdownProps {
|
||||||
testID?: string;
|
testID?: string;
|
||||||
style?: StyleProp<TextStyle>[];
|
style?: StyleProp<TextStyle>[];
|
||||||
onLinkPress?: TOnLinkPress;
|
onLinkPress?: TOnLinkPress;
|
||||||
|
isTranslated?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
type TLiteral = {
|
type TLiteral = {
|
||||||
|
@ -93,9 +94,7 @@ class Markdown extends PureComponent<IMarkdownProps, any> {
|
||||||
|
|
||||||
constructor(props: IMarkdownProps) {
|
constructor(props: IMarkdownProps) {
|
||||||
super(props);
|
super(props);
|
||||||
if (!this.isNewMarkdown) {
|
this.renderer = this.createRenderer();
|
||||||
this.renderer = this.createRenderer();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
createRenderer = () =>
|
createRenderer = () =>
|
||||||
|
@ -310,13 +309,24 @@ class Markdown extends PureComponent<IMarkdownProps, any> {
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { msg, md, mentions, channels, navToRoomInfo, useRealName, username = '', getCustomEmoji, onLinkPress } = this.props;
|
const {
|
||||||
|
msg,
|
||||||
|
md,
|
||||||
|
mentions,
|
||||||
|
channels,
|
||||||
|
navToRoomInfo,
|
||||||
|
useRealName,
|
||||||
|
username = '',
|
||||||
|
getCustomEmoji,
|
||||||
|
onLinkPress,
|
||||||
|
isTranslated
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isNewMarkdown) {
|
if (this.isNewMarkdown && !isTranslated) {
|
||||||
return (
|
return (
|
||||||
<NewMarkdown
|
<NewMarkdown
|
||||||
username={username}
|
username={username}
|
||||||
|
|
|
@ -18,13 +18,29 @@ import MarkdownContext from './MarkdownContext';
|
||||||
|
|
||||||
interface IParagraphProps {
|
interface IParagraphProps {
|
||||||
value: ParagraphProps['value'];
|
value: ParagraphProps['value'];
|
||||||
|
forceTrim?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
const Inline = ({ value }: IParagraphProps): React.ReactElement | null => {
|
const Inline = ({ value, forceTrim }: IParagraphProps): React.ReactElement | null => {
|
||||||
const { useRealName, username, navToRoomInfo, mentions, channels } = useContext(MarkdownContext);
|
const { useRealName, username, navToRoomInfo, mentions, channels } = useContext(MarkdownContext);
|
||||||
return (
|
return (
|
||||||
<Text style={styles.inline}>
|
<Text style={styles.inline}>
|
||||||
{value.map(block => {
|
{value.map((block, index) => {
|
||||||
|
// We are forcing trim when is a `[ ](https://https://open.rocket.chat/) plain_text`
|
||||||
|
// to clean the empty spaces
|
||||||
|
if (forceTrim) {
|
||||||
|
if (index === 0 && block.type === 'LINK') {
|
||||||
|
block.value.label.value =
|
||||||
|
// Need to update the @rocket.chat/message-parser to understand that the label can be a Markup | Markup[]
|
||||||
|
// https://github.com/RocketChat/fuselage/blob/461ecf661d9ff4a46390957c915e4352fa942a7c/packages/message-parser/src/definitions.ts#L141
|
||||||
|
// @ts-ignore
|
||||||
|
block.value?.label?.value?.toString().trimLeft() || block?.value?.label?.[0]?.value?.toString().trimLeft();
|
||||||
|
}
|
||||||
|
if (index === 1 && block.type !== 'LINK') {
|
||||||
|
block.value = block.value?.toString().trimLeft();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (block.type) {
|
switch (block.type) {
|
||||||
case 'IMAGE':
|
case 'IMAGE':
|
||||||
return <Image value={block.value} />;
|
return <Image value={block.value} />;
|
||||||
|
|
|
@ -381,27 +381,6 @@ export const BlockQuote = () => (
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
||||||
const rocketChatLink = [
|
|
||||||
{
|
|
||||||
type: 'PARAGRAPH',
|
|
||||||
value: [
|
|
||||||
{
|
|
||||||
type: 'LINK',
|
|
||||||
value: {
|
|
||||||
src: {
|
|
||||||
type: 'PLAIN_TEXT',
|
|
||||||
value: 'https://rocket.chat'
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
type: 'PLAIN_TEXT',
|
|
||||||
value: 'https://rocket.chat'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
];
|
|
||||||
|
|
||||||
const markdownLink = [
|
const markdownLink = [
|
||||||
{
|
{
|
||||||
type: 'PARAGRAPH',
|
type: 'PARAGRAPH',
|
||||||
|
@ -487,7 +466,6 @@ const markdownLinkWithEmphasis = [
|
||||||
|
|
||||||
export const Links = () => (
|
export const Links = () => (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<NewMarkdown tokens={rocketChatLink} />
|
|
||||||
<NewMarkdown tokens={markdownLink} />
|
<NewMarkdown tokens={markdownLink} />
|
||||||
<NewMarkdown tokens={markdownLinkWithEmphasis} />
|
<NewMarkdown tokens={markdownLinkWithEmphasis} />
|
||||||
</View>
|
</View>
|
||||||
|
@ -806,3 +784,128 @@ export const InlineKatex = () => (
|
||||||
<NewMarkdown tokens={inlineKatex} />
|
<NewMarkdown tokens={inlineKatex} />
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const messageQuote = {
|
||||||
|
/**
|
||||||
|
# Hello head 1
|
||||||
|
[ ](https://google.com)
|
||||||
|
*/
|
||||||
|
headAndLink: [
|
||||||
|
{ type: 'HEADING', level: 1, value: [{ type: 'PLAIN_TEXT', value: 'Hello head 1' }] },
|
||||||
|
{ type: 'LINE_BREAK' },
|
||||||
|
{
|
||||||
|
type: 'PARAGRAPH',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
type: 'LINK',
|
||||||
|
value: { src: { type: 'PLAIN_TEXT', value: 'https://google.com' }, label: { type: 'PLAIN_TEXT', value: ' ' } }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
/**
|
||||||
|
# Head 1 as the first line then line break and after paragraph
|
||||||
|
bla bla bla bla bla bla
|
||||||
|
bla bla bla bla bla bla
|
||||||
|
[ ](https://google.com)
|
||||||
|
*/
|
||||||
|
headTextAndLink: [
|
||||||
|
{
|
||||||
|
type: 'HEADING',
|
||||||
|
level: 1,
|
||||||
|
value: [{ type: 'PLAIN_TEXT', value: 'Head 1 as the first line then line break and after paragraph' }]
|
||||||
|
},
|
||||||
|
{ type: 'LINE_BREAK' },
|
||||||
|
{ type: 'PARAGRAPH', value: [{ type: 'PLAIN_TEXT', value: 'bla bla bla bla bla bla ' }] },
|
||||||
|
{ type: 'PARAGRAPH', value: [{ type: 'PLAIN_TEXT', value: 'bla bla bla bla bla bla ' }] },
|
||||||
|
{
|
||||||
|
type: 'PARAGRAPH',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
type: 'LINK',
|
||||||
|
value: { src: { type: 'PLAIN_TEXT', value: 'https://google.com' }, label: { type: 'PLAIN_TEXT', value: ' ' } }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
/**
|
||||||
|
[ ](permalink from message)\n# Head 1 after a forced line break
|
||||||
|
asdas asd asd asd
|
||||||
|
*/
|
||||||
|
headTextAndQuote: [
|
||||||
|
{
|
||||||
|
type: 'PARAGRAPH',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
type: 'LINK',
|
||||||
|
value: {
|
||||||
|
src: { type: 'PLAIN_TEXT', value: 'https://open.rocket.chat/direct/subaru123?msg=QB42gWcaO6BgqtLTo' },
|
||||||
|
label: { type: 'PLAIN_TEXT', value: ' ' }
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ type: 'PLAIN_TEXT', value: ' ' }
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{ type: 'HEADING', level: 1, value: [{ type: 'PLAIN_TEXT', value: 'Head 1 after a forced line break' }] },
|
||||||
|
{ type: 'LINE_BREAK' },
|
||||||
|
{ type: 'PARAGRAPH', value: [{ type: 'PLAIN_TEXT', value: 'Description' }] }
|
||||||
|
],
|
||||||
|
/**
|
||||||
|
[ ](https://google.com) *There is a link before this bold separated by single space*
|
||||||
|
*/
|
||||||
|
linkAndBoldText: [
|
||||||
|
{
|
||||||
|
type: 'PARAGRAPH',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
type: 'LINK',
|
||||||
|
value: { src: { type: 'PLAIN_TEXT', value: 'https://google.com' }, label: { type: 'PLAIN_TEXT', value: ' ' } }
|
||||||
|
},
|
||||||
|
{ type: 'PLAIN_TEXT', value: ' ' },
|
||||||
|
{ type: 'BOLD', value: [{ type: 'PLAIN_TEXT', value: 'There is a link before this bold separated by single space' }] }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
simpleQuote: [
|
||||||
|
{
|
||||||
|
type: 'PARAGRAPH',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
type: 'LINK',
|
||||||
|
value: {
|
||||||
|
src: {
|
||||||
|
type: 'PLAIN_TEXT',
|
||||||
|
value: 'https://open.rocket.chat/group/quoteeee9798789?msg=ZZp6t2dCRX4TqExht'
|
||||||
|
},
|
||||||
|
// format of label for servers greater or equal than 6.0
|
||||||
|
label: [
|
||||||
|
{
|
||||||
|
type: 'PLAIN_TEXT',
|
||||||
|
value: ' '
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'PARAGRAPH',
|
||||||
|
value: [
|
||||||
|
{
|
||||||
|
type: 'PLAIN_TEXT',
|
||||||
|
value: 'Quoting a message wrote before'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
export const MessageQuote = () => (
|
||||||
|
<View style={styles.container}>
|
||||||
|
<NewMarkdown tokens={messageQuote.headAndLink} />
|
||||||
|
<NewMarkdown tokens={messageQuote.headTextAndLink} />
|
||||||
|
<NewMarkdown tokens={messageQuote.headTextAndQuote} />
|
||||||
|
<NewMarkdown tokens={messageQuote.linkAndBoldText} />
|
||||||
|
<NewMarkdown tokens={messageQuote.simpleQuote} />
|
||||||
|
</View>
|
||||||
|
);
|
||||||
|
|
|
@ -17,7 +17,9 @@ const OrderedList = ({ value }: IOrderedListProps): React.ReactElement => {
|
||||||
{value.map(item => (
|
{value.map(item => (
|
||||||
<View style={styles.row} key={item.number?.toString()}>
|
<View style={styles.row} key={item.number?.toString()}>
|
||||||
<Text style={[styles.text, { color: colors.bodyText }]}>{item.number}. </Text>
|
<Text style={[styles.text, { color: colors.bodyText }]}>{item.number}. </Text>
|
||||||
<Inline value={item.value} />
|
<Text style={{ color: colors.bodyText }}>
|
||||||
|
<Inline value={item.value} />
|
||||||
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -12,10 +12,28 @@ interface IParagraphProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Paragraph = ({ value }: IParagraphProps) => {
|
const Paragraph = ({ value }: IParagraphProps) => {
|
||||||
|
let forceTrim = false;
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
|
if (
|
||||||
|
value?.[0]?.type === 'LINK' &&
|
||||||
|
// Need to update the @rocket.chat/message-parser to understand that the label can be a Markup | Markup[]
|
||||||
|
// https://github.com/RocketChat/fuselage/blob/461ecf661d9ff4a46390957c915e4352fa942a7c/packages/message-parser/src/definitions.ts#L141
|
||||||
|
// @ts-ignore
|
||||||
|
(value?.[0]?.value?.label?.value?.toString().trim() === '' || value?.[0]?.value?.label?.[0]?.value?.toString().trim() === '')
|
||||||
|
) {
|
||||||
|
// We are returning null when we receive a message like this: `[ ](https://open.rocket.chat/)\nplain_text`
|
||||||
|
// to avoid render a line empty above the the message
|
||||||
|
if (value.length === 1) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (value.length === 2 && value?.[1]?.type === 'PLAIN_TEXT' && value?.[1]?.value?.toString().trim() === '') {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
forceTrim = true;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Text style={[styles.text, { color: themes[theme].bodyText }]}>
|
<Text style={[styles.text, { color: themes[theme].bodyText }]}>
|
||||||
<Inline value={value} />
|
<Inline value={value} forceTrim={forceTrim} />
|
||||||
</Text>
|
</Text>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,7 +18,9 @@ const UnorderedList = ({ value }: IUnorderedListProps) => {
|
||||||
{value.map(item => (
|
{value.map(item => (
|
||||||
<View style={styles.row}>
|
<View style={styles.row}>
|
||||||
<Text style={[styles.text, { color: themes[theme].bodyText }]}>- </Text>
|
<Text style={[styles.text, { color: themes[theme].bodyText }]}>- </Text>
|
||||||
<Inline value={item.value} />
|
<Text style={{ color: themes[theme].bodyText }}>
|
||||||
|
<Inline value={item.value} />
|
||||||
|
</Text>
|
||||||
</View>
|
</View>
|
||||||
))}
|
))}
|
||||||
</View>
|
</View>
|
||||||
|
|
|
@ -20,6 +20,8 @@ import { TGetCustomEmoji } from '../../definitions/IEmoji';
|
||||||
import { IAttachment } from '../../definitions';
|
import { IAttachment } from '../../definitions';
|
||||||
import { TSupportedThemes } from '../../theme';
|
import { TSupportedThemes } from '../../theme';
|
||||||
import { downloadAudioFile } from '../../lib/methods/audioFile';
|
import { downloadAudioFile } from '../../lib/methods/audioFile';
|
||||||
|
import EventEmitter from '../../lib/methods/helpers/events';
|
||||||
|
import { PAUSE_AUDIO } from './constants';
|
||||||
|
|
||||||
interface IButton {
|
interface IButton {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
|
@ -128,6 +130,11 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
this.sound.setOnPlaybackStatusUpdate(this.onPlaybackStatusUpdate);
|
this.sound.setOnPlaybackStatusUpdate(this.onPlaybackStatusUpdate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pauseSound = () => {
|
||||||
|
EventEmitter.removeListener(PAUSE_AUDIO, this.pauseSound);
|
||||||
|
this.togglePlayPause();
|
||||||
|
};
|
||||||
|
|
||||||
async componentDidMount() {
|
async componentDidMount() {
|
||||||
const { file, messageId } = this.props;
|
const { file, messageId } = this.props;
|
||||||
const { baseUrl, user } = this.context;
|
const { baseUrl, user } = this.context;
|
||||||
|
@ -183,6 +190,7 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
}
|
}
|
||||||
|
|
||||||
async componentWillUnmount() {
|
async componentWillUnmount() {
|
||||||
|
EventEmitter.removeListener(PAUSE_AUDIO, this.pauseSound);
|
||||||
try {
|
try {
|
||||||
await this.sound.stopAsync();
|
await this.sound.stopAsync();
|
||||||
} catch {
|
} catch {
|
||||||
|
@ -221,6 +229,7 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
try {
|
try {
|
||||||
await this.sound.stopAsync();
|
await this.sound.stopAsync();
|
||||||
this.setState({ paused: true, currentTime: 0 });
|
this.setState({ paused: true, currentTime: 0 });
|
||||||
|
EventEmitter.removeListener(PAUSE_AUDIO, this.pauseSound);
|
||||||
} catch {
|
} catch {
|
||||||
// do nothing
|
// do nothing
|
||||||
}
|
}
|
||||||
|
@ -243,7 +252,10 @@ class MessageAudio extends React.Component<IMessageAudioProps, IMessageAudioStat
|
||||||
try {
|
try {
|
||||||
if (paused) {
|
if (paused) {
|
||||||
await this.sound.pauseAsync();
|
await this.sound.pauseAsync();
|
||||||
|
EventEmitter.removeListener(PAUSE_AUDIO, this.pauseSound);
|
||||||
} else {
|
} else {
|
||||||
|
EventEmitter.emit(PAUSE_AUDIO);
|
||||||
|
EventEmitter.addEventListener(PAUSE_AUDIO, this.pauseSound);
|
||||||
await Audio.setAudioModeAsync(mode);
|
await Audio.setAudioModeAsync(mode);
|
||||||
await this.sound.playAsync();
|
await this.sound.playAsync();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import React from 'react';
|
import React, { useRef } from 'react';
|
||||||
|
|
||||||
import { messageBlockWithContext } from '../UIKit/MessageBlock';
|
import { messageBlockWithContext } from '../UIKit/MessageBlock';
|
||||||
import { IMessageBlocks } from './interfaces';
|
import { IMessageBlocks } from './interfaces';
|
||||||
|
@ -6,25 +6,29 @@ import { IMessageBlocks } from './interfaces';
|
||||||
const Blocks = React.memo(({ blocks, id: mid, rid, blockAction }: IMessageBlocks) => {
|
const Blocks = React.memo(({ blocks, id: mid, rid, blockAction }: IMessageBlocks) => {
|
||||||
if (blocks && blocks.length > 0) {
|
if (blocks && blocks.length > 0) {
|
||||||
const appId = blocks[0]?.appId || '';
|
const appId = blocks[0]?.appId || '';
|
||||||
return React.createElement(
|
// eslint-disable-next-line react-hooks/rules-of-hooks
|
||||||
messageBlockWithContext({
|
const comp = useRef(
|
||||||
action: async ({ actionId, value, blockId }: { actionId: string; value: string; blockId: string }) => {
|
React.createElement(
|
||||||
if (blockAction) {
|
messageBlockWithContext({
|
||||||
await blockAction({
|
action: async ({ actionId, value, blockId }: { actionId: string; value: string; blockId: string }) => {
|
||||||
actionId,
|
if (blockAction) {
|
||||||
appId,
|
await blockAction({
|
||||||
value,
|
actionId,
|
||||||
blockId,
|
appId,
|
||||||
rid,
|
value,
|
||||||
mid
|
blockId,
|
||||||
});
|
rid,
|
||||||
}
|
mid
|
||||||
},
|
});
|
||||||
appId,
|
}
|
||||||
rid
|
},
|
||||||
}),
|
appId,
|
||||||
{ blocks }
|
rid
|
||||||
|
}),
|
||||||
|
{ blocks }
|
||||||
|
)
|
||||||
);
|
);
|
||||||
|
return comp.current;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,14 +1,20 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
import { themes } from '../../../../lib/constants';
|
|
||||||
import { CustomIcon } from '../../../CustomIcon';
|
import { CustomIcon } from '../../../CustomIcon';
|
||||||
import styles from '../../styles';
|
import styles from '../../styles';
|
||||||
import { useTheme } from '../../../../theme';
|
import { useTheme } from '../../../../theme';
|
||||||
|
|
||||||
const ReadReceipt = React.memo(({ isReadReceiptEnabled, unread }: { isReadReceiptEnabled?: boolean; unread?: boolean }) => {
|
const ReadReceipt = React.memo(({ isReadReceiptEnabled, unread }: { isReadReceiptEnabled?: boolean; unread?: boolean }) => {
|
||||||
const { theme } = useTheme();
|
const { colors } = useTheme();
|
||||||
if (isReadReceiptEnabled && !unread && unread !== null) {
|
if (isReadReceiptEnabled) {
|
||||||
return <CustomIcon name='check' color={themes[theme].tintColor} size={16} style={styles.rightIcons} />;
|
return (
|
||||||
|
<CustomIcon
|
||||||
|
name='check'
|
||||||
|
color={!unread && unread !== null ? colors.tintColor : colors.auxiliaryTintColor}
|
||||||
|
size={16}
|
||||||
|
style={styles.rightIcons}
|
||||||
|
/>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
|
@ -64,6 +64,7 @@ const Content = React.memo(
|
||||||
useRealName={props.useRealName}
|
useRealName={props.useRealName}
|
||||||
theme={theme}
|
theme={theme}
|
||||||
onLinkPress={onLinkPress}
|
onLinkPress={onLinkPress}
|
||||||
|
isTranslated={props.isTranslated}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
export const DISCUSSION = 'discussion';
|
export const DISCUSSION = 'discussion';
|
||||||
export const THREAD = 'thread';
|
export const THREAD = 'thread';
|
||||||
|
export const PAUSE_AUDIO = 'pause_audio';
|
||||||
|
|
|
@ -233,7 +233,9 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
|
||||||
!(previousItem.groupable === false || item.groupable === false || broadcast === true) &&
|
!(previousItem.groupable === false || item.groupable === false || broadcast === true) &&
|
||||||
// @ts-ignore TODO: IMessage vs IMessageFromServer non-sense
|
// @ts-ignore TODO: IMessage vs IMessageFromServer non-sense
|
||||||
item.ts - previousItem.ts < Message_GroupingPeriod * 1000 &&
|
item.ts - previousItem.ts < Message_GroupingPeriod * 1000 &&
|
||||||
previousItem.tmid === item.tmid
|
previousItem.tmid === item.tmid &&
|
||||||
|
item.t !== 'rm' &&
|
||||||
|
previousItem.t !== 'rm'
|
||||||
) {
|
) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -270,7 +272,7 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
|
||||||
|
|
||||||
get isInfo(): string | boolean {
|
get isInfo(): string | boolean {
|
||||||
const { item } = this.props;
|
const { item } = this.props;
|
||||||
if (['e2e', 'discussion-created', 'jitsi_call_started'].includes(item.t)) {
|
if (['e2e', 'discussion-created', 'jitsi_call_started', 'videoconf'].includes(item.t)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return item.t;
|
return item.t;
|
||||||
|
@ -376,10 +378,13 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
|
||||||
} = item;
|
} = item;
|
||||||
|
|
||||||
let message = msg;
|
let message = msg;
|
||||||
|
let isTranslated = false;
|
||||||
// "autoTranslateRoom" and "autoTranslateLanguage" are properties from the subscription
|
// "autoTranslateRoom" and "autoTranslateLanguage" are properties from the subscription
|
||||||
// "autoTranslateMessage" is a toggle between "View Original" and "Translate" state
|
// "autoTranslateMessage" is a toggle between "View Original" and "Translate" state
|
||||||
if (autoTranslateRoom && autoTranslateMessage && autoTranslateLanguage) {
|
if (autoTranslateRoom && autoTranslateMessage && autoTranslateLanguage) {
|
||||||
message = getMessageTranslation(item, autoTranslateLanguage) || message;
|
const messageTranslated = getMessageTranslation(item, autoTranslateLanguage);
|
||||||
|
isTranslated = !!messageTranslated;
|
||||||
|
message = messageTranslated || message;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -455,6 +460,7 @@ class MessageContainer extends React.Component<IMessageContainerProps, IMessageC
|
||||||
blockAction={blockAction}
|
blockAction={blockAction}
|
||||||
highlighted={highlighted}
|
highlighted={highlighted}
|
||||||
comment={comment}
|
comment={comment}
|
||||||
|
isTranslated={isTranslated}
|
||||||
/>
|
/>
|
||||||
</MessageContext.Provider>
|
</MessageContext.Provider>
|
||||||
);
|
);
|
||||||
|
|
|
@ -63,6 +63,7 @@ export interface IMessageContent {
|
||||||
comment?: string;
|
comment?: string;
|
||||||
hasError: boolean;
|
hasError: boolean;
|
||||||
isHeader: boolean;
|
isHeader: boolean;
|
||||||
|
isTranslated: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IMessageEmoji {
|
export interface IMessageEmoji {
|
||||||
|
|
|
@ -65,6 +65,7 @@ const messagesWithAuthorName: MessageTypesValues[] = [
|
||||||
'room_changed_avatar',
|
'room_changed_avatar',
|
||||||
'room_e2e_disabled',
|
'room_e2e_disabled',
|
||||||
'room_e2e_enabled',
|
'room_e2e_enabled',
|
||||||
|
'room-allowed-reacting',
|
||||||
'room-disallowed-reacting',
|
'room-disallowed-reacting',
|
||||||
'room-set-read-only',
|
'room-set-read-only',
|
||||||
'room-removed-read-only',
|
'room-removed-read-only',
|
||||||
|
|
|
@ -8,7 +8,15 @@ import { TThreadMessageModel } from './IThreadMessage';
|
||||||
import { TThreadModel } from './IThread';
|
import { TThreadModel } from './IThread';
|
||||||
import { IUrl, IUrlFromServer } from './IUrl';
|
import { IUrl, IUrlFromServer } from './IUrl';
|
||||||
|
|
||||||
export type MessageType = 'jitsi_call_started' | 'discussion-created' | 'e2e' | 'load_more' | 'rm' | 'uj' | MessageTypeLoad | MessageTypesValues;
|
export type MessageType =
|
||||||
|
| 'jitsi_call_started'
|
||||||
|
| 'discussion-created'
|
||||||
|
| 'e2e'
|
||||||
|
| 'load_more'
|
||||||
|
| 'rm'
|
||||||
|
| 'uj'
|
||||||
|
| MessageTypeLoad
|
||||||
|
| MessageTypesValues;
|
||||||
|
|
||||||
export interface IUserMessage {
|
export interface IUserMessage {
|
||||||
_id: string;
|
_id: string;
|
||||||
|
@ -222,6 +230,7 @@ export type MessageTypesValues =
|
||||||
| 'room-allowed-reacting'
|
| 'room-allowed-reacting'
|
||||||
| 'room-disallowed-reacting'
|
| 'room-disallowed-reacting'
|
||||||
| 'command'
|
| 'command'
|
||||||
|
| 'videoconf'
|
||||||
| LivechatMessageTypes
|
| LivechatMessageTypes
|
||||||
| TeamMessageTypes
|
| TeamMessageTypes
|
||||||
| VoipMessageTypesValues
|
| VoipMessageTypesValues
|
||||||
|
|
|
@ -91,6 +91,7 @@ export interface ISubscription {
|
||||||
livechatData?: any;
|
livechatData?: any;
|
||||||
tags?: string[];
|
tags?: string[];
|
||||||
E2EKey?: string;
|
E2EKey?: string;
|
||||||
|
E2ESuggestedKey?: string;
|
||||||
encrypted?: boolean;
|
encrypted?: boolean;
|
||||||
e2eKeyId?: string;
|
e2eKeyId?: string;
|
||||||
avatarETag?: string;
|
avatarETag?: string;
|
||||||
|
@ -145,6 +146,7 @@ export interface IServerSubscription extends IRocketChatRecord {
|
||||||
onHold?: boolean;
|
onHold?: boolean;
|
||||||
encrypted?: boolean;
|
encrypted?: boolean;
|
||||||
E2EKey?: string;
|
E2EKey?: string;
|
||||||
|
E2ESuggestedKey?: string;
|
||||||
unreadAlert?: 'default' | 'all' | 'mentions' | 'nothing';
|
unreadAlert?: 'default' | 'all' | 'mentions' | 'nothing';
|
||||||
|
|
||||||
fname?: unknown;
|
fname?: unknown;
|
||||||
|
|
|
@ -5,6 +5,7 @@ export interface IUpload {
|
||||||
rid?: string;
|
rid?: string;
|
||||||
path: string;
|
path: string;
|
||||||
name?: string;
|
name?: string;
|
||||||
|
tmid?: string;
|
||||||
description?: string;
|
description?: string;
|
||||||
size: number;
|
size: number;
|
||||||
type?: string;
|
type?: string;
|
||||||
|
@ -12,6 +13,7 @@ export interface IUpload {
|
||||||
progress?: number;
|
progress?: number;
|
||||||
error?: boolean;
|
error?: boolean;
|
||||||
subscription?: { id: string };
|
subscription?: { id: string };
|
||||||
|
msg?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type TUploadModel = IUpload & Model;
|
export type TUploadModel = IUpload & Model;
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
import type { AtLeast } from './utils';
|
||||||
|
import type { IRocketChatRecord } from './IRocketChatRecord';
|
||||||
|
import type { IRoom } from './IRoom';
|
||||||
|
import type { IUser } from './IUser';
|
||||||
|
import type { IMessage } from './IMessage';
|
||||||
|
|
||||||
|
export enum VideoConferenceStatus {
|
||||||
|
CALLING = 0,
|
||||||
|
STARTED = 1,
|
||||||
|
EXPIRED = 2,
|
||||||
|
ENDED = 3,
|
||||||
|
DECLINED = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
export type DirectCallInstructions = {
|
||||||
|
type: 'direct';
|
||||||
|
callee: IUser['_id'];
|
||||||
|
callId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ConferenceInstructions = {
|
||||||
|
type: 'videoconference';
|
||||||
|
callId: string;
|
||||||
|
rid: IRoom['_id'];
|
||||||
|
};
|
||||||
|
|
||||||
|
export type LivechatInstructions = {
|
||||||
|
type: 'livechat';
|
||||||
|
callId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type VideoConferenceType = DirectCallInstructions['type'] | ConferenceInstructions['type'] | LivechatInstructions['type'];
|
||||||
|
|
||||||
|
export interface IVideoConferenceUser extends Pick<Required<IUser>, '_id' | 'username' | 'name' | 'avatarETag'> {
|
||||||
|
ts: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IVideoConference extends IRocketChatRecord {
|
||||||
|
type: VideoConferenceType;
|
||||||
|
rid: string;
|
||||||
|
users: IVideoConferenceUser[];
|
||||||
|
status: VideoConferenceStatus;
|
||||||
|
messages: {
|
||||||
|
started?: IMessage['_id'];
|
||||||
|
ended?: IMessage['_id'];
|
||||||
|
};
|
||||||
|
url?: string;
|
||||||
|
|
||||||
|
createdBy: Pick<IUser, '_id' | 'username' | 'name'>;
|
||||||
|
createdAt: Date;
|
||||||
|
|
||||||
|
endedBy?: Pick<IUser, '_id' | 'username' | 'name'>;
|
||||||
|
endedAt?: Date;
|
||||||
|
|
||||||
|
providerName: string;
|
||||||
|
providerData?: Record<string, any>;
|
||||||
|
|
||||||
|
ringing?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IDirectVideoConference extends IVideoConference {
|
||||||
|
type: 'direct';
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IGroupVideoConference extends IVideoConference {
|
||||||
|
type: 'videoconference';
|
||||||
|
anonymousUsers: number;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ILivechatVideoConference extends IVideoConference {
|
||||||
|
type: 'livechat';
|
||||||
|
}
|
||||||
|
|
||||||
|
export type VideoConference = IDirectVideoConference | IGroupVideoConference | ILivechatVideoConference;
|
||||||
|
|
||||||
|
export type VideoConferenceInstructions = DirectCallInstructions | ConferenceInstructions | LivechatInstructions;
|
||||||
|
|
||||||
|
export const isDirectVideoConference = (call: VideoConference | undefined | null): call is IDirectVideoConference =>
|
||||||
|
call?.type === 'direct';
|
||||||
|
|
||||||
|
export const isGroupVideoConference = (call: VideoConference | undefined | null): call is IGroupVideoConference =>
|
||||||
|
call?.type === 'videoconference';
|
||||||
|
|
||||||
|
export const isLivechatVideoConference = (call: VideoConference | undefined | null): call is ILivechatVideoConference =>
|
||||||
|
call?.type === 'livechat';
|
||||||
|
|
||||||
|
type GroupVideoConferenceCreateData = Omit<IGroupVideoConference, 'createdBy'> & { createdBy: IUser['_id'] };
|
||||||
|
type DirectVideoConferenceCreateData = Omit<IDirectVideoConference, 'createdBy'> & { createdBy: IUser['_id'] };
|
||||||
|
type LivechatVideoConferenceCreateData = Omit<ILivechatVideoConference, 'createdBy'> & { createdBy: IUser['_id'] };
|
||||||
|
|
||||||
|
export type VideoConferenceCreateData = AtLeast<
|
||||||
|
DirectVideoConferenceCreateData | GroupVideoConferenceCreateData | LivechatVideoConferenceCreateData,
|
||||||
|
'createdBy' | 'type' | 'rid' | 'providerName' | 'providerData'
|
||||||
|
>;
|
|
@ -29,6 +29,7 @@ export * from './ISearch';
|
||||||
export * from './TUserStatus';
|
export * from './TUserStatus';
|
||||||
export * from './IProfile';
|
export * from './IProfile';
|
||||||
export * from './IReaction';
|
export * from './IReaction';
|
||||||
|
export * from './ERoomType';
|
||||||
|
|
||||||
export interface IBaseScreen<T extends Record<string, object | undefined>, S extends string> {
|
export interface IBaseScreen<T extends Record<string, object | undefined>, S extends string> {
|
||||||
navigation: StackNavigationProp<T, S>;
|
navigation: StackNavigationProp<T, S>;
|
||||||
|
|
|
@ -12,6 +12,12 @@ export type E2eEndpoints = {
|
||||||
'e2e.updateGroupKey': {
|
'e2e.updateGroupKey': {
|
||||||
POST: (params: { uid: string; rid: string; key: string }) => {};
|
POST: (params: { uid: string; rid: string; key: string }) => {};
|
||||||
};
|
};
|
||||||
|
'e2e.acceptSuggestedGroupKey': {
|
||||||
|
POST: (params: { rid: string }) => {};
|
||||||
|
};
|
||||||
|
'e2e.rejectSuggestedGroupKey': {
|
||||||
|
POST: (params: { rid: string }) => {};
|
||||||
|
};
|
||||||
'e2e.setRoomKeyID': {
|
'e2e.setRoomKeyID': {
|
||||||
POST: (params: { rid: string; keyID: string }) => {};
|
POST: (params: { rid: string; keyID: string }) => {};
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
import { VideoConference } from '../../IVideoConference';
|
||||||
|
|
||||||
export type VideoConferenceEndpoints = {
|
export type VideoConferenceEndpoints = {
|
||||||
'video-conference/jitsi.update-timeout': {
|
'video-conference/jitsi.update-timeout': {
|
||||||
POST: (params: { roomId: string }) => void;
|
POST: (params: { roomId: string }) => void;
|
||||||
|
@ -8,4 +10,18 @@ export type VideoConferenceEndpoints = {
|
||||||
'video-conference.start': {
|
'video-conference.start': {
|
||||||
POST: (params: { roomId: string }) => { url: string };
|
POST: (params: { roomId: string }) => { url: string };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
'video-conference.cancel': {
|
||||||
|
POST: (params: { callId: string }) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
'video-conference.info': {
|
||||||
|
GET: (params: { callId: string }) => VideoConference & {
|
||||||
|
capabilities: {
|
||||||
|
mic?: boolean;
|
||||||
|
cam?: boolean;
|
||||||
|
title?: boolean;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
export type Optional<T, K extends keyof T> = Omit<T, K> & Partial<T>;
|
||||||
|
|
||||||
|
export type ExtractKeys<T, K extends keyof T, U> = T[K] extends U ? K : never;
|
||||||
|
|
||||||
|
export type ValueOf<T> = T[keyof T];
|
||||||
|
|
||||||
|
export type UnionToIntersection<T> = (T extends any ? (x: T) => void : never) extends (x: infer U) => void ? U : never;
|
||||||
|
|
||||||
|
export type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T;
|
||||||
|
|
||||||
|
// `T extends any` is a trick to apply a operator to each member of a union
|
||||||
|
export type KeyOfEach<T> = T extends any ? keyof T : never;
|
||||||
|
|
||||||
|
// Taken from https://effectivetypescript.com/2020/04/09/jsonify/
|
||||||
|
export type Jsonify<T> = T extends Date
|
||||||
|
? string
|
||||||
|
: T extends object
|
||||||
|
? {
|
||||||
|
[k in keyof T]: Jsonify<T[k]>;
|
||||||
|
}
|
||||||
|
: T;
|
||||||
|
|
||||||
|
export type AtLeast<T, K extends keyof T> = Partial<T> & Pick<T, K>;
|
||||||
|
|
||||||
|
export type RequiredField<T, K extends keyof T> = T & Required<Pick<T, K>>;
|
|
@ -73,19 +73,14 @@ const QueueListView = React.memo(() => {
|
||||||
|
|
||||||
const onPressItem = (item = {} as IOmnichannelRoom) => {
|
const onPressItem = (item = {} as IOmnichannelRoom) => {
|
||||||
logEvent(events.QL_GO_ROOM);
|
logEvent(events.QL_GO_ROOM);
|
||||||
if (isMasterDetail) {
|
|
||||||
navigation.navigate('DrawerNavigator');
|
|
||||||
} else {
|
|
||||||
navigation.navigate('RoomsListView');
|
|
||||||
}
|
|
||||||
|
|
||||||
goRoom({
|
goRoom({
|
||||||
item: {
|
item: {
|
||||||
...item,
|
...item,
|
||||||
// we're calling v as visitor on our mergeSubscriptionsRooms
|
// we're calling v as visitor on our mergeSubscriptionsRooms
|
||||||
visitor: item.v
|
visitor: item.v
|
||||||
},
|
},
|
||||||
isMasterDetail
|
isMasterDetail,
|
||||||
|
popToRoot: true
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -25,14 +25,9 @@ export const LANGUAGES: ILanguage[] = [
|
||||||
file: () => require('./locales/en.json')
|
file: () => require('./locales/en.json')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '简体中文',
|
label: 'العربية',
|
||||||
value: 'zh-CN',
|
value: 'ar',
|
||||||
file: () => require('./locales/zh-CN.json')
|
file: () => require('./locales/ar.json')
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '繁體中文',
|
|
||||||
value: 'zh-TW',
|
|
||||||
file: () => require('./locales/zh-TW.json')
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Deutsch',
|
label: 'Deutsch',
|
||||||
|
@ -44,11 +39,31 @@ export const LANGUAGES: ILanguage[] = [
|
||||||
value: 'es-ES',
|
value: 'es-ES',
|
||||||
file: () => require('./locales/es-ES.json')
|
file: () => require('./locales/es-ES.json')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Finnish',
|
||||||
|
value: 'fi',
|
||||||
|
file: () => require('./locales/fi.json')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'Français',
|
label: 'Français',
|
||||||
value: 'fr',
|
value: 'fr',
|
||||||
file: () => require('./locales/fr.json')
|
file: () => require('./locales/fr.json')
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
label: 'Italiano',
|
||||||
|
value: 'it',
|
||||||
|
file: () => require('./locales/it.json')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '日本語',
|
||||||
|
value: 'ja',
|
||||||
|
file: () => require('./locales/ja.json')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'Nederlands',
|
||||||
|
value: 'nl',
|
||||||
|
file: () => require('./locales/nl.json')
|
||||||
|
},
|
||||||
{
|
{
|
||||||
label: 'Português (BR)',
|
label: 'Português (BR)',
|
||||||
value: 'pt-BR',
|
value: 'pt-BR',
|
||||||
|
@ -65,24 +80,14 @@ export const LANGUAGES: ILanguage[] = [
|
||||||
file: () => require('./locales/ru.json')
|
file: () => require('./locales/ru.json')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Nederlands',
|
label: 'Slovenian (Slovenia)',
|
||||||
value: 'nl',
|
value: 'sl-SI',
|
||||||
file: () => require('./locales/nl.json')
|
file: () => require('./locales/sl-SI.json')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Italiano',
|
label: 'Swedish',
|
||||||
value: 'it',
|
value: 'sv',
|
||||||
file: () => require('./locales/it.json')
|
file: () => require('./locales/sv.json')
|
||||||
},
|
|
||||||
{
|
|
||||||
label: '日本語',
|
|
||||||
value: 'ja',
|
|
||||||
file: () => require('./locales/ja.json')
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: 'العربية',
|
|
||||||
value: 'ar',
|
|
||||||
file: () => require('./locales/ar.json')
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Türkçe',
|
label: 'Türkçe',
|
||||||
|
@ -90,9 +95,14 @@ export const LANGUAGES: ILanguage[] = [
|
||||||
file: () => require('./locales/tr.json')
|
file: () => require('./locales/tr.json')
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'Slovenian (Slovenia)',
|
label: '简体中文',
|
||||||
value: 'sl-SI',
|
value: 'zh-CN',
|
||||||
file: () => require('./locales/sl-SI.json')
|
file: () => require('./locales/zh-CN.json')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '繁體中文',
|
||||||
|
value: 'zh-TW',
|
||||||
|
file: () => require('./locales/zh-TW.json')
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
@ -256,6 +256,11 @@
|
||||||
"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",
|
||||||
|
"Get_link": "Link erhalten",
|
||||||
|
"User_joined_the_channel": "ist dem Kanal beigetreten",
|
||||||
|
"User_joined_the_conversation": "hat sich dem Gespräch angeschlossen",
|
||||||
|
"User_joined_the_team": "ist dem Team beigetreten",
|
||||||
|
"User_left_this_channel": "hat den Kanal verlassen",
|
||||||
"Has_left_the_team": "Hat das Team verlassen",
|
"Has_left_the_team": "Hat das Team verlassen",
|
||||||
"Hide_System_Messages": "Systemnachrichten ausblenden",
|
"Hide_System_Messages": "Systemnachrichten ausblenden",
|
||||||
"Hide_type_messages": "\"{{type}}\"-Nachrichten ausblenden",
|
"Hide_type_messages": "\"{{type}}\"-Nachrichten ausblenden",
|
||||||
|
@ -321,6 +326,7 @@
|
||||||
"Message_accessibility": "Nachricht von {{user}} um {{time}}: {{message}}",
|
"Message_accessibility": "Nachricht von {{user}} um {{time}}: {{message}}",
|
||||||
"Message_actions": "Nachrichtenaktionen",
|
"Message_actions": "Nachrichtenaktionen",
|
||||||
"Message_pinned": "Eine Nachricht wurde angeheftet",
|
"Message_pinned": "Eine Nachricht wurde angeheftet",
|
||||||
|
"Message_removed": "Nachricht entfernt",
|
||||||
"Message_starred": "Nachricht favorisiert",
|
"Message_starred": "Nachricht favorisiert",
|
||||||
"Message_unstarred": "Nachricht nicht mehr favorisiert",
|
"Message_unstarred": "Nachricht nicht mehr favorisiert",
|
||||||
"message": "Nachricht",
|
"message": "Nachricht",
|
||||||
|
@ -348,6 +354,7 @@
|
||||||
"No_mentioned_messages": "Keine Nachrichten mit Erwähnungen",
|
"No_mentioned_messages": "Keine Nachrichten mit Erwähnungen",
|
||||||
"No_pinned_messages": "Keine angehefteten Nachrichten",
|
"No_pinned_messages": "Keine angehefteten Nachrichten",
|
||||||
"No_results_found": "Keine Ergebnisse gefunden",
|
"No_results_found": "Keine Ergebnisse gefunden",
|
||||||
|
"No_members_found": "Keine Mitglieder gefunden",
|
||||||
"No_starred_messages": "Keine markierten Nachrichten",
|
"No_starred_messages": "Keine markierten Nachrichten",
|
||||||
"No_thread_messages": "Keine Threadnachrichten",
|
"No_thread_messages": "Keine Threadnachrichten",
|
||||||
"No_label_provided": "Kein(e) {{label}} gesetzt.",
|
"No_label_provided": "Kein(e) {{label}} gesetzt.",
|
||||||
|
@ -443,11 +450,21 @@
|
||||||
"Roles": "Rollen",
|
"Roles": "Rollen",
|
||||||
"Room_actions": "Room-Aktionen",
|
"Room_actions": "Room-Aktionen",
|
||||||
"Room_changed_announcement": "Room-Ansage geändert in: {{announcement}} von {{userBy}}",
|
"Room_changed_announcement": "Room-Ansage geändert in: {{announcement}} von {{userBy}}",
|
||||||
|
"room_avatar_changed": "hat den Raum-Avatar geändert",
|
||||||
"Room_changed_description": "Room-beschreibung geändert in: {{description}} von {{userBy}}",
|
"Room_changed_description": "Room-beschreibung geändert in: {{description}} von {{userBy}}",
|
||||||
|
"changed_room_description": "hat die Raumbeschreibung geändert zu: {{description}}",
|
||||||
|
"changed_room_announcement": "hat die Ankündigung des Raumes geändert zu: {{announcement}}",
|
||||||
|
"room_changed_type": "hat den Raum geändert zu {{type}}",
|
||||||
|
"room_changed_topic_to": "hat das Thema des Raumes geändert zu: {{topic}}",
|
||||||
"Room_Files": "Room-Dateien",
|
"Room_Files": "Room-Dateien",
|
||||||
"Room_Info_Edit": "Room-Info bearbeiten",
|
"Room_Info_Edit": "Room-Info bearbeiten",
|
||||||
"Room_Info": "Room-Info",
|
"Room_Info": "Room-Info",
|
||||||
"Room_Members": "Room-Mitglieder",
|
"Room_Members": "Room-Mitglieder",
|
||||||
|
"Room_name_changed_to": "hat den Namen des Raumes geändert zu: {{name}}",
|
||||||
|
"room_disallowed_reactions": "hat Reaktionen untersagt",
|
||||||
|
"room_allowed_reactions": "hat Reaktionen erlaubt",
|
||||||
|
"room_removed_read_only_permission": "hat die Nur-Lese-Berechtigung entfernt",
|
||||||
|
"room_set_read_only_permission": "hat den Raum auf \"Nur Lesen\" gesetzt",
|
||||||
"SAVE": "SPEICHERN",
|
"SAVE": "SPEICHERN",
|
||||||
"Save_Changes": "Änderungen speichern",
|
"Save_Changes": "Änderungen speichern",
|
||||||
"Save": "speichern",
|
"Save": "speichern",
|
||||||
|
@ -463,6 +480,7 @@
|
||||||
"Search_Messages": "Nachrichten suchen",
|
"Search_Messages": "Nachrichten suchen",
|
||||||
"Search": "Suche",
|
"Search": "Suche",
|
||||||
"Search_by": "Suche nach",
|
"Search_by": "Suche nach",
|
||||||
|
"Search_emoji": "Emoji suchen",
|
||||||
"Search_global_users": "Nach globalen Benutzern suchen",
|
"Search_global_users": "Nach globalen Benutzern suchen",
|
||||||
"Search_global_users_description": "Wenn aktiviert, Können Sie nach Benutzern von anderen Unternehmen oder Servern suchen.",
|
"Search_global_users_description": "Wenn aktiviert, Können Sie nach Benutzern von anderen Unternehmen oder Servern suchen.",
|
||||||
"Seconds": "{{second}} Sekunden",
|
"Seconds": "{{second}} Sekunden",
|
||||||
|
@ -547,13 +565,21 @@
|
||||||
"Unsupported_system_message": "Nicht unterstützte Systemmeldung",
|
"Unsupported_system_message": "Nicht unterstützte Systemmeldung",
|
||||||
"Updating": "Aktualisierung …",
|
"Updating": "Aktualisierung …",
|
||||||
"Uploading": "Hochladen",
|
"Uploading": "Hochladen",
|
||||||
|
"FileUpload_Error": "Fehler bei Datei-Upload",
|
||||||
|
"Upload_in_progress": "Upload in Bearbeitung",
|
||||||
"Upload_file_question_mark": "Datei hochladen?",
|
"Upload_file_question_mark": "Datei hochladen?",
|
||||||
"User": "Benutzer",
|
"User": "Benutzer",
|
||||||
"Users": "Benutzer",
|
"Users": "Benutzer",
|
||||||
|
"User_added_to": "hat {{userAdded}} hinzugefügt",
|
||||||
"User_Info": "Benutzerinfo",
|
"User_Info": "Benutzerinfo",
|
||||||
"User_has_been_key": "Benutzer wurde {{key}}",
|
"User_has_been_key": "Benutzer wurde {{key}}",
|
||||||
"User_is_no_longer_role_by_": "{{user}} ist nicht länger {{role}} von {{userBy}}",
|
"User_is_no_longer_role_by_": "{{user}} ist nicht länger {{role}} von {{userBy}}",
|
||||||
|
"User_has_been_muted": "hat {{userMuted}} stumm gestellt",
|
||||||
|
"User_has_been_removed": "hat {{userRemoved}} entfernt",
|
||||||
"User_sent_an_attachment": "{{user}}: eine Datei gesendet",
|
"User_sent_an_attachment": "{{user}}: eine Datei gesendet",
|
||||||
|
"User_has_been_unmuted": "hat {{userUnmuted}} nicht mehr auf stumm gestellt",
|
||||||
|
"Defined_user_as_role": "hat {{user}} als {{role}} gesetzt",
|
||||||
|
"Removed_user_as_role": "hat {{user}} als {{role}} entfernt",
|
||||||
"Username_is_empty": "Der Benutzername ist leer",
|
"Username_is_empty": "Der Benutzername ist leer",
|
||||||
"Username": "Benutzername",
|
"Username": "Benutzername",
|
||||||
"Username_or_email": "Benutzername oder E-Mail-Adresse",
|
"Username_or_email": "Benutzername oder E-Mail-Adresse",
|
||||||
|
@ -695,6 +721,8 @@
|
||||||
"Message_Ignored": "Nachricht ignoriert. Antippen um sie zu zeigen.",
|
"Message_Ignored": "Nachricht ignoriert. Antippen um sie zu zeigen.",
|
||||||
"Enter_workspace_URL": "Arbeitsbereich-URL",
|
"Enter_workspace_URL": "Arbeitsbereich-URL",
|
||||||
"Workspace_URL_Example": "z.B. https://rocketchat.deine-firma.de",
|
"Workspace_URL_Example": "z.B. https://rocketchat.deine-firma.de",
|
||||||
|
"Enabled_E2E_Encryption_for_this_room": "hat E2E-Verschlüsselung für diesen Raum aktiviert",
|
||||||
|
"Disabled_E2E_Encryption_for_this_room": "hat E2E-Verschlüsselung für diesen Raum deaktiviert",
|
||||||
"Teams": "Teams",
|
"Teams": "Teams",
|
||||||
"No_team_channels_found": "Keine Kanäle gefunden",
|
"No_team_channels_found": "Keine Kanäle gefunden",
|
||||||
"Team_not_found": "Team nicht gefunden",
|
"Team_not_found": "Team nicht gefunden",
|
||||||
|
@ -778,7 +806,11 @@
|
||||||
"Unsupported_format": "Nicht unterstütztes Format",
|
"Unsupported_format": "Nicht unterstütztes Format",
|
||||||
"Downloaded_file": "Heruntergeladene Datei",
|
"Downloaded_file": "Heruntergeladene Datei",
|
||||||
"Error_Download_file": "Fehler beim Herunterladen der Datei",
|
"Error_Download_file": "Fehler beim Herunterladen der Datei",
|
||||||
|
"added__roomName__to_this_team": "hat #{{roomName}} diesem Team hinzugefügt",
|
||||||
|
"Added__username__to_this_team": "hat @{{user_added}} zu einem Team hinzugefügt",
|
||||||
"Converting_team_to_channel": "Team in Channel umwandeln",
|
"Converting_team_to_channel": "Team in Channel umwandeln",
|
||||||
|
"Converted__roomName__to_a_team": "hat #{{roomName}} in ein Team umgewandelt",
|
||||||
|
"Converted__roomName__to_a_channel": "hat #{{roomName}} in einen Kanal umgewandelt",
|
||||||
"Deleted__roomName__": "#{{roomName}} gelöscht",
|
"Deleted__roomName__": "#{{roomName}} gelöscht",
|
||||||
"Message_HideType_added_user_to_team": "Nachrichten \"Benutzer zu Team hinzugefügt\" ausblenden",
|
"Message_HideType_added_user_to_team": "Nachrichten \"Benutzer zu Team hinzugefügt\" ausblenden",
|
||||||
"Message_HideType_removed_user_from_team": "Nachrichten \"Benutzer aus Team entfernt\" ausblenden",
|
"Message_HideType_removed_user_from_team": "Nachrichten \"Benutzer aus Team entfernt\" ausblenden",
|
||||||
|
@ -789,7 +821,10 @@
|
||||||
"Message_HideType_user_converted_to_team": "Nachrichten \"Benutzer hat Channel in Team konvertiert\" ausblenden",
|
"Message_HideType_user_converted_to_team": "Nachrichten \"Benutzer hat Channel in Team konvertiert\" ausblenden",
|
||||||
"Message_HideType_user_deleted_room_from_team": "Nachrichten \"Benutzer hat Room aus Team gelöscht\" ausblenden",
|
"Message_HideType_user_deleted_room_from_team": "Nachrichten \"Benutzer hat Room aus Team gelöscht\" ausblenden",
|
||||||
"Message_HideType_user_removed_room_from_team": "Nachrichten \"Benutzer hat Room aus Team entfernt\" ausblenden",
|
"Message_HideType_user_removed_room_from_team": "Nachrichten \"Benutzer hat Room aus Team entfernt\" ausblenden",
|
||||||
|
"Removed__roomName__from_the_team": "hat #{{roomName}} aus diesem Team entfernt",
|
||||||
|
"Removed__username__from_the_team": "hat @{{userRemoved}} aus diesem Team entfernt",
|
||||||
"User_joined_team": "ist dem Team beigetreten",
|
"User_joined_team": "ist dem Team beigetreten",
|
||||||
|
"User_left_team": "hat das Team verlassen",
|
||||||
"Place_chat_on_hold": "Chat in die Warteschleife stellen",
|
"Place_chat_on_hold": "Chat in die Warteschleife stellen",
|
||||||
"Would_like_to_place_on_hold": "Möchten Sie diesen Chat in die Warteschleife legen?",
|
"Would_like_to_place_on_hold": "Möchten Sie diesen Chat in die Warteschleife legen?",
|
||||||
"Open_Livechats": "Offene Livechats",
|
"Open_Livechats": "Offene Livechats",
|
||||||
|
@ -808,5 +843,20 @@
|
||||||
"totp-invalid": "Code oder Passwort ist falsch",
|
"totp-invalid": "Code oder Passwort ist falsch",
|
||||||
"Close_Chat": "Chat schließen",
|
"Close_Chat": "Chat schließen",
|
||||||
"Select_tags": "Tags auswählen",
|
"Select_tags": "Tags auswählen",
|
||||||
"Broadcast_hint": "Nur autorisierte Benutzer können neue Nachrichten schreiben, die anderen Benutzer können jedoch antworten"
|
"Skip": "Überspringen",
|
||||||
|
"N_Selected_members": "{{n}} ausgewählt",
|
||||||
|
"Broadcast": "Broadcast",
|
||||||
|
"Broadcast_hint": "Nur autorisierte Benutzer können neue Nachrichten schreiben, die anderen Benutzer können jedoch antworten",
|
||||||
|
"Team_hint_private": "Nur eingeladene Benutzer können beitreten",
|
||||||
|
"Team_hint_public": "Wenn deaktiviert, kann jeder dem Team beitreten",
|
||||||
|
"Team_hint_not_read_only": "Jeder Benutzer in diesem Team kann Nachrichten schreiben",
|
||||||
|
"Team_hint_encrypted": "Ende-zu-Ende-verschlüsseltes Team. In verschlüsselten Team ist keine Suche möglich und Benachrichtigungen zeigen möglicherweise nicht den Nachrichteninhalt an.",
|
||||||
|
"Team_hint_encrypted_not_available": "Nur für private Teams verfügbar",
|
||||||
|
"Channel_hint_private": "Nur eingeladene Nutzer können auf diesen Kanal zugreifen",
|
||||||
|
"Channel_hint_public": "Jeder kann auf diesen Kanal zugreifen",
|
||||||
|
"Channel_hint_encrypted": "Ende-zu-Ende verschlüsselter Kanal. Die Suche funktioniert nicht mit verschlüsselten Channels. In Benachrichtigungen wird der Inhalt der Nachricht möglicherweise nicht angezeigt.",
|
||||||
|
"Channel_hint_not_read_only": "Alle Nutzer im Kanal können neue Nachrichten schreiben",
|
||||||
|
"Channel_hint_encrypted_not_available": "Nicht verfügbar in öffentlichen Kanälen",
|
||||||
|
"Read_only_hint": "Nur autorisierte Benutzer können neue Nachrichten schreiben",
|
||||||
|
"Discussion": "Diskussion"
|
||||||
}
|
}
|
|
@ -565,6 +565,8 @@
|
||||||
"Unsupported_system_message": "Unsupported system message",
|
"Unsupported_system_message": "Unsupported system message",
|
||||||
"Updating": "Updating...",
|
"Updating": "Updating...",
|
||||||
"Uploading": "Uploading",
|
"Uploading": "Uploading",
|
||||||
|
"FileUpload_Error": "File Upload Error",
|
||||||
|
"Upload_in_progress": "Upload in progress",
|
||||||
"Upload_file_question_mark": "Upload file?",
|
"Upload_file_question_mark": "Upload file?",
|
||||||
"User": "User",
|
"User": "User",
|
||||||
"Users": "Users",
|
"Users": "Users",
|
||||||
|
@ -862,6 +864,16 @@
|
||||||
"Select_Members": "Select Members",
|
"Select_Members": "Select Members",
|
||||||
"Also_send_thread_message_to_channel_behavior": "Also send thread message to channel",
|
"Also_send_thread_message_to_channel_behavior": "Also send thread message to channel",
|
||||||
"Accounts_Default_User_Preferences_alsoSendThreadToChannel_Description": "Allow users to select the Also send to channel behavior",
|
"Accounts_Default_User_Preferences_alsoSendThreadToChannel_Description": "Allow users to select the Also send to channel behavior",
|
||||||
|
"Waiting_for_answer": "Waiting for answer",
|
||||||
|
"Call_ended": "Call ended",
|
||||||
|
"Call_was_not_answered": "Call was not answered",
|
||||||
|
"Call_back": "Call Back",
|
||||||
|
"Call_again": "Call Again",
|
||||||
|
"Call_ongoing": "Call Ongoing",
|
||||||
|
"Joined": "Joined",
|
||||||
|
"Calling": "Calling...",
|
||||||
|
"Start_a_call": "Start a call",
|
||||||
|
"Call": "Call",
|
||||||
"Reply_in_direct_message": "Reply in Direct Message",
|
"Reply_in_direct_message": "Reply in Direct Message",
|
||||||
"room_archived": "archived room",
|
"room_archived": "archived room",
|
||||||
"room_unarchived": "unarchived room"
|
"room_unarchived": "unarchived room"
|
||||||
|
|
|
@ -183,6 +183,7 @@
|
||||||
"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",
|
||||||
|
"Get_link": "Obtener enlace",
|
||||||
"In_App_And_Desktop": "En la aplicación y en el escritorio",
|
"In_App_And_Desktop": "En la aplicación y en el escritorio",
|
||||||
"In_App_and_Desktop_Alert_info": "Muestra un banner en la parte superior de la pantalla cuando la aplicación esté abierta y muestra una notificación en el escritorio",
|
"In_App_and_Desktop_Alert_info": "Muestra un banner en la parte superior de la pantalla cuando la aplicación esté abierta y muestra una notificación en el escritorio",
|
||||||
"Invisible": "Invisible",
|
"Invisible": "Invisible",
|
||||||
|
@ -214,6 +215,7 @@
|
||||||
"Message_accessibility": "Mensaje de {{user}} a las {{time}}: {{message}}",
|
"Message_accessibility": "Mensaje de {{user}} a las {{time}}: {{message}}",
|
||||||
"Message_actions": "Acciones de mensaje",
|
"Message_actions": "Acciones de mensaje",
|
||||||
"Message_pinned": "Mensaje fijado",
|
"Message_pinned": "Mensaje fijado",
|
||||||
|
"Message_removed": "Mensaje eliminado",
|
||||||
"message": "mensaje",
|
"message": "mensaje",
|
||||||
"messages": "mensajes",
|
"messages": "mensajes",
|
||||||
"Messages": "Mensajes",
|
"Messages": "Mensajes",
|
||||||
|
@ -423,6 +425,5 @@
|
||||||
"Server_selection_numbers": "Seleccionar servidor 1...9",
|
"Server_selection_numbers": "Seleccionar servidor 1...9",
|
||||||
"Add_server": "Añadir servidor",
|
"Add_server": "Añadir servidor",
|
||||||
"New_line": "Nueva línea",
|
"New_line": "Nueva línea",
|
||||||
"Broadcast_hint": "Sólo los usuarios autorizados pueden escribir nuevos mensajes, el resto podrán responder sobre los mismos.",
|
"Broadcast_hint": "Sólo los usuarios autorizados pueden escribir nuevos mensajes, el resto podrán responder sobre los mismos."
|
||||||
"Get_link": "Obtener enlace"
|
|
||||||
}
|
}
|
|
@ -1 +1,880 @@
|
||||||
{ }
|
{
|
||||||
|
"__count__empty_rooms_will_be_removed_automatically": "{{count}} tyhjää huonetta poistetaan.",
|
||||||
|
"__count__empty_room_will_be_removed_automatically": "{{count}} tyhjä huone poistetaan.",
|
||||||
|
"1_person_reacted": "1 henkilö reagoi",
|
||||||
|
"1_user": "1 käyttäjä",
|
||||||
|
"error-action-not-allowed": "{{action}} ei ole sallittu",
|
||||||
|
"error-application-not-found": "Sovellusta ei löydy",
|
||||||
|
"error-archived-duplicate-name": "Nimellä {{room_name}} on arkistoitu kanava",
|
||||||
|
"error-avatar-invalid-url": "Virheellinen avatarin URL-osoite: {{url}}",
|
||||||
|
"error-avatar-url-handling": "Virhe käsiteltäessä avatarin asetusta URL-osoitteesta ({{url}}) käyttäjälle {{username}}",
|
||||||
|
"error-cant-invite-for-direct-room": "Et voi kutsua käyttäjää suoriin huoneisiin",
|
||||||
|
"error-could-not-change-email": "Ei voitu vaihtaa sähköpostia",
|
||||||
|
"error-could-not-change-name": "Ei voitu vaihtaa nimeä",
|
||||||
|
"error-could-not-change-username": "Ei voitu vaihtaa käyttäjätunnusta",
|
||||||
|
"error-could-not-change-status": "Ei voitu vaihtaa tilaa",
|
||||||
|
"error-delete-protected-role": "Ei voi poistaa suojattua roolia",
|
||||||
|
"error-department-not-found": "Osastoa ei löydy",
|
||||||
|
"error-direct-message-file-upload-not-allowed": "Tiedostojen jakaminen ei ole sallittua suorissa viesteissä",
|
||||||
|
"error-duplicate-channel-name": "Kanava nimeltä {{room_name}} on jo olemassa",
|
||||||
|
"error-email-domain-blacklisted": "Sähköpostin toimialue on estettyjen luettelossa",
|
||||||
|
"error-email-send-failed": "Virhe yritettäessä lähettää sähköpostia: {{message}}",
|
||||||
|
"error-save-image": "Virhe tallennettaessa kuvaa",
|
||||||
|
"error-save-video": "Virhe tallennettaessa videota",
|
||||||
|
"error-field-unavailable": "{{field}} on jo käytössä :(",
|
||||||
|
"error-file-too-large": "Tiedosto on liian suuri",
|
||||||
|
"error-not-permission-to-upload-file": "Sinulla ei ole oikeutta ladata tiedostoja",
|
||||||
|
"error-importer-not-defined": "Tuontia ei ole määritetty oikein, siitä puuttuu Import-luokka.",
|
||||||
|
"error-input-is-not-a-valid-field": "{{input}} ei ole kelvollinen {{field}}",
|
||||||
|
"error-invalid-actionlink": "Virheellinen toimintalinkki",
|
||||||
|
"error-invalid-arguments": "Virheelliset argumentit",
|
||||||
|
"error-invalid-asset": "Virheellinen resurssi",
|
||||||
|
"error-invalid-channel": "Virheellinen kanava.",
|
||||||
|
"error-invalid-channel-start-with-chars": "Virheellinen kanava. Aloita @- tai #-merkillä",
|
||||||
|
"error-invalid-custom-field": "Virheellinen mukautettu kenttä",
|
||||||
|
"error-invalid-custom-field-name": "Virheellinen mukautetun kentän nimi. Käytä vain kirjaimia, numeroita, yhdysviivoja ja alaviivoja.",
|
||||||
|
"error-invalid-date": "Virheellinen päivämäärä.",
|
||||||
|
"error-invalid-description": "Virheellinen kuvaus",
|
||||||
|
"error-invalid-domain": "Virheellinen toimialue",
|
||||||
|
"error-invalid-email": "Virheellinen sähköposti {{email}}",
|
||||||
|
"error-invalid-email-address": "Virheellinen sähköpostiosoite",
|
||||||
|
"error-invalid-file-height": "Virheellinen tiedoston korkeus",
|
||||||
|
"error-invalid-file-type": "Virheellinen tiedostotyyppi",
|
||||||
|
"error-invalid-file-width": "Virheellinen tiedoston leveys",
|
||||||
|
"error-invalid-from-address": "Virheellinen lähettäjän osoite.",
|
||||||
|
"error-invalid-integration": "Virheellinen integraatio",
|
||||||
|
"error-invalid-message": "Virheellinen viesti",
|
||||||
|
"error-invalid-method": "Virheellinen tapa",
|
||||||
|
"error-invalid-name": "Virheellinen nimi",
|
||||||
|
"error-invalid-password": "Virheellinen salasana",
|
||||||
|
"error-invalid-redirectUri": "Virheellinen redirectUri",
|
||||||
|
"error-invalid-role": "Virheellinen rooli",
|
||||||
|
"error-invalid-room": "Virheellinen huone",
|
||||||
|
"error-invalid-room-name": "{{room_name}} ei ole kelvollinen huoneen nimi",
|
||||||
|
"error-invalid-room-type": "{{type}} ei ole kelvollinen huoneen tyyppi.",
|
||||||
|
"error-invalid-settings": "Asetukset ovat virheelliset",
|
||||||
|
"error-invalid-subscription": "Virheellinen tilaus",
|
||||||
|
"error-invalid-token": "Virheellinen tunnus",
|
||||||
|
"error-invalid-triggerWords": "Virheelliset triggerWords-sanat",
|
||||||
|
"error-invalid-urls": "Virheelliset URL-osoitteet",
|
||||||
|
"error-invalid-user": "Virheellinen käyttäjä",
|
||||||
|
"error-invalid-username": "Virheellinen käyttäjätunnus",
|
||||||
|
"error-invalid-webhook-response": "Webhook-URL ilmoitti muun tilan kuin 200",
|
||||||
|
"error-message-deleting-blocked": "Viestin poistaminen on estetty",
|
||||||
|
"error-message-editing-blocked": "Viestin muokkaus on estetty",
|
||||||
|
"error-message-size-exceeded": "Viestin koko on yli Message_MaxAllowedSize",
|
||||||
|
"error-missing-unsubscribe-link": "Sinun on annettava [unsubscribe] -linkki.",
|
||||||
|
"error-no-owner-channel": "Et omista kanavaa",
|
||||||
|
"error-no-tokens-for-this-user": "Käyttäjällä ei ole tunnuksia",
|
||||||
|
"error-not-allowed": "Ei sallittu",
|
||||||
|
"error-not-authorized": "Ei valtuutettu",
|
||||||
|
"error-push-disabled": "Push-ilmoitukset ovat poissa käytöstä",
|
||||||
|
"error-remove-last-owner": "Tämä on viimeinen omistaja. Aseta uusi omistaja ennen kuin poistat tämän.",
|
||||||
|
"error-role-in-use": "Roolia ei voi poistaa, koska se on käytössä",
|
||||||
|
"error-role-name-required": "Roolin nimi on pakollinen",
|
||||||
|
"error-password-same-as-current": "Annettu salasana sama kuin nykyinen salasana",
|
||||||
|
"error-the-field-is-required": "Kenttä {{field}} on pakollinen.",
|
||||||
|
"error-too-many-requests": "Virhe, liikaa pyyntöjä. Hidasta vähän. Odota {{seconds}} sekuntia ennen uutta yritystä.",
|
||||||
|
"error-user-is-not-activated": "Käyttäjää ei ole aktivoitu",
|
||||||
|
"error-user-has-no-roles": "Käyttäjällä ei ole rooleja",
|
||||||
|
"error-user-limit-exceeded": "Käyttäjien määrä, jonka yrität kutsua kanavalle #channel_name, ylittää järjestelmänvalvojan asettaman rajan",
|
||||||
|
"error-user-not-in-room": "Käyttäjä ei ole tässä huoneessa",
|
||||||
|
"error-user-registration-custom-field": "error-user-registration-custom-field",
|
||||||
|
"error-user-registration-disabled": "Käyttäjän rekisteröinti on poissa käytöstä",
|
||||||
|
"error-user-registration-secret": "Käyttäjän rekisteröinti on sallittu ainoastaan salaisen URL-osoitteen kautta",
|
||||||
|
"error-you-are-last-owner": "Olet viimeinen omistaja. Aseta uusi omistaja ennen huoneesta lähtöä.",
|
||||||
|
"error-status-not-allowed": "Näkymätön tila on poistettu käytöstä",
|
||||||
|
"A_new_owner_will_be_assigned_automatically_to__count__rooms": "Uusi omistaja liitetään automaattisesti {{count}} huoneeseen.",
|
||||||
|
"A_new_owner_will_be_assigned_automatically_to__count__room": "Uusi omistaja liitetään automaattisesti {{count}} huoneeseen.",
|
||||||
|
"Actions": "Toimet",
|
||||||
|
"Activity": "Toiminta",
|
||||||
|
"Add_Reaction": "Lisää reaktio",
|
||||||
|
"Add_Server": "Lisää palvelin",
|
||||||
|
"Add_users": "Lisää käyttäjiä",
|
||||||
|
"Admin_Panel": "Hallintapaneeli",
|
||||||
|
"Agent": "Agentti",
|
||||||
|
"Alert": "Hälytys",
|
||||||
|
"alert": "hälytys",
|
||||||
|
"alerts": "hälytystä",
|
||||||
|
"All_users_in_the_channel_can_write_new_messages": "Kaikki kanavan käyttäjät voivat kirjoittaa uusia viestejä",
|
||||||
|
"All_users_in_the_team_can_write_new_messages": "Kaikki tiimin käyttäjät voivat kirjoittaa uusia viestejä",
|
||||||
|
"A_meaningful_name_for_the_discussion_room": "Mielekäs nimi keskusteluhuoneelle",
|
||||||
|
"All": "Kaikki",
|
||||||
|
"All_Messages": "Kaikki viestit",
|
||||||
|
"Allow_Reactions": "Salli reaktiot",
|
||||||
|
"Alphabetical": "Aakkosjärjestys",
|
||||||
|
"and_more": "ja muuta",
|
||||||
|
"and": "ja",
|
||||||
|
"announcement": "ilmoitus",
|
||||||
|
"Announcement": "Ilmoitus",
|
||||||
|
"Apply_Your_Certificate": "Käytä varmennetta",
|
||||||
|
"ARCHIVE": "ARKISTO",
|
||||||
|
"archive": "arkisto",
|
||||||
|
"are_typing": "kirjoittavat",
|
||||||
|
"Are_you_sure_question_mark": "Oletko varma?",
|
||||||
|
"Are_you_sure_you_want_to_delete_your_account": "Haluatko varmasti poistaa tilisi?",
|
||||||
|
"Deleting_a_user_will_delete_all_messages": "Käyttäjän poistaminen poistaa myös kaikki kyseisen käyttäjän viestit, huoneet ja tiimit. Tätä ei voi kumota.",
|
||||||
|
"Are_you_sure_you_want_to_leave_the_room": "Haluatko varmasti poistua huoneesta {{room}}?",
|
||||||
|
"Audio": "Ääni",
|
||||||
|
"Authenticating": "Todennetaan",
|
||||||
|
"Automatic": "Automaattinen",
|
||||||
|
"Auto_Translate": "Automaattikäännös",
|
||||||
|
"Avatar_changed_successfully": "Avatar on vaihdettu!",
|
||||||
|
"Avatar_Url": "Avatarin URL-osoite",
|
||||||
|
"Away": "Poissa",
|
||||||
|
"Back": "Takaisin",
|
||||||
|
"Black": "Musta",
|
||||||
|
"Block_user": "Estä käyttäjä",
|
||||||
|
"Browser": "Selain",
|
||||||
|
"Busy": "Varattu",
|
||||||
|
"By_proceeding_you_are_agreeing": "Jatkamalla hyväksyt",
|
||||||
|
"Cancel_editing": "Peruuta muokkaus",
|
||||||
|
"Cancel_recording": "Peruuta tallennus",
|
||||||
|
"Cancel": "Peruuta",
|
||||||
|
"changing_avatar": "vaihtaa avataria",
|
||||||
|
"creating_channel": "luo kanavaa",
|
||||||
|
"creating_invite": "luo kutsua",
|
||||||
|
"Channel_Name": "Kanavan nimi",
|
||||||
|
"Channels": "Kanavat",
|
||||||
|
"Chats": "Keskustelut",
|
||||||
|
"Chat_started": "Keskustelu aloitettu",
|
||||||
|
"Call_already_ended": "Puhelu on jo päättynyt!",
|
||||||
|
"Clear_cookies_alert": "Haluatko tyhjentää kaikki evästeet?",
|
||||||
|
"Clear_cookies_desc": "Tämä toiminto tyhjentää kaikki kirjautumisevästeet, joten voit kirjautua muille tileille.",
|
||||||
|
"Clear_cookies_yes": "Kyllä, tyhjennä evästeet",
|
||||||
|
"Clear_cookies_no": "Ei, säilytä evästeet",
|
||||||
|
"Click_to_join": "Liity napsauttamalla!",
|
||||||
|
"Close": "Sulje",
|
||||||
|
"Close_emoji_selector": "Sulje emojien valitsin",
|
||||||
|
"Closing_chat": "Suljetaan keskustelua",
|
||||||
|
"Change_language_loading": "Vaihdetaan kieltä.",
|
||||||
|
"Chat_closed_by_agent": "Agentti sulki keskustelun",
|
||||||
|
"Choose": "Valitse",
|
||||||
|
"Choose_from_library": "Valitse kirjastosta",
|
||||||
|
"Choose_file": "Valitse tiedosto",
|
||||||
|
"Choose_where_you_want_links_be_opened": "Valitse, missä linkit avataan",
|
||||||
|
"Code": "Koodi",
|
||||||
|
"Code_or_password_invalid": "Koodi tai salasana virheellinen",
|
||||||
|
"Conversation_closed": "Keskustelu suljettu",
|
||||||
|
"Collaborative": "Yhteistyö",
|
||||||
|
"Confirm": "Vahvista",
|
||||||
|
"Connect": "Yhdistä",
|
||||||
|
"Connected": "Yhdistetty",
|
||||||
|
"connecting_server": "yhdistää palvelimeen",
|
||||||
|
"Connecting": "Yhdistetään...",
|
||||||
|
"Contact_us": "Ota yhteyttä",
|
||||||
|
"Contact_your_server_admin": "Ota yhteys palvelimen järjestelmänvalvojaan.",
|
||||||
|
"Continue_with": "Jatka:",
|
||||||
|
"Copied_to_clipboard": "Kopioitu leikepöydälle!",
|
||||||
|
"Copy": "Kopioi",
|
||||||
|
"Conversation": "Keskustelu",
|
||||||
|
"Certificate_password": "Varmenteen salasana",
|
||||||
|
"Clear_cache": "Tyhjennä paikallisen palvelimen välimuisti",
|
||||||
|
"Clear_cache_loading": "Tyhjennetään välimuistia.",
|
||||||
|
"Whats_the_password_for_your_certificate": "Mikä on varmenteesi salasana?",
|
||||||
|
"Create_account": "Luo tili",
|
||||||
|
"Create_Channel": "Luo kanava",
|
||||||
|
"Create_Direct_Messages": "Luo suoria viestejä",
|
||||||
|
"Create_Discussion": "Luo keskustelu",
|
||||||
|
"Created_snippet": "loi katkelman",
|
||||||
|
"Create_a_new_workspace": "Luo uusi työtila",
|
||||||
|
"Create": "Luo",
|
||||||
|
"Custom_Status": "Mukautettu tila",
|
||||||
|
"Dark": "Tumma",
|
||||||
|
"Dark_level": "Tumman taso",
|
||||||
|
"Default": "Oletus",
|
||||||
|
"Default_browser": "Oletusselain",
|
||||||
|
"Delete_Room_Warning": "Huomeen poistaminen poistaa kaikki huoneessa olevat viestit. Tätä ei voi kumota.",
|
||||||
|
"Department": "Osasto",
|
||||||
|
"delete": "poista",
|
||||||
|
"Delete": "Poista",
|
||||||
|
"DELETE": "POISTA",
|
||||||
|
"Delete_Account": "Poista tili",
|
||||||
|
"Delete_Account_confirm": "Kyllä, poista",
|
||||||
|
"move": "siirrä",
|
||||||
|
"deleting_room": "poistaa huonetta",
|
||||||
|
"description": "kuvaus",
|
||||||
|
"Description": "Kuvaus",
|
||||||
|
"Desktop_Options": "Työpöytäasetukset",
|
||||||
|
"Desktop_Notifications": "Työpöytäilmoitukset",
|
||||||
|
"Desktop_Alert_info": "Nämä ilmoitukset näkyvät työpöydällä",
|
||||||
|
"Directory": "Hakemisto",
|
||||||
|
"Direct_Messages": "Suorat viestit",
|
||||||
|
"Disable_notifications": "Poista käytöstä ilmoitukset",
|
||||||
|
"Discussions": "Keskustelut",
|
||||||
|
"Discussion_Desc": "Pysy selvillä tapahtumista! Luomalla keskustelun luot valitsemasi kanavan alikanavan, ja keskustelut liitetään yhteen.",
|
||||||
|
"Discussion_name": "Keskustelun nimi",
|
||||||
|
"Done": "Valmis",
|
||||||
|
"Dont_Have_An_Account": "Eikö sinulla ole tiliä?",
|
||||||
|
"Do_you_have_an_account": "Onko sinulla tili?",
|
||||||
|
"Do_you_have_a_certificate": "Onko sinulla varmenne?",
|
||||||
|
"Do_you_really_want_to_key_this_room_question_mark": "Haluatko varmasti {{key}} tämän huoneen?",
|
||||||
|
"E2E_Encryption": "Täysi salaus",
|
||||||
|
"E2E_How_It_Works_info1": "Nyt voit luoda salattuja yksityisiä ryhmiä ja suoria viestejä. Voit myös muuttaa nykyisiä yksityisiä ryhmiä tai suoria viestejä salatuksi.",
|
||||||
|
"E2E_How_It_Works_info2": "Tämä on *täysi salaus*, joten viestiesi salaamiseen ja salauksen purkuun käytettävää avainta ei tallenneta palvelimeen. Siksi *sinun on tallennettava tämä salasana turvalliseen paikkaan*, johon pääset myöhemmin tarvittaessa.",
|
||||||
|
"E2E_How_It_Works_info3": "Jos jatkat, täyden salauksen salasana luodaan automaattisesti.",
|
||||||
|
"E2E_How_It_Works_info4": "Voit myös määrittää uuden salasanan salausavaimellesi milloin tahansa missä tahansa selaimessa, jossa olet antanut nykyisen täyden salauksen salasanan.",
|
||||||
|
"edit": "muokkaa",
|
||||||
|
"edited": "muokkasi",
|
||||||
|
"Edit": "Muokkaa",
|
||||||
|
"Edit_Status": "Muokkaa tilaa",
|
||||||
|
"Edit_Invite": "Muokkaa kutsua",
|
||||||
|
"End_to_end_encrypted_room": "Täysin salattu huone",
|
||||||
|
"end_to_end_encryption": "täysi salaus",
|
||||||
|
"Email_Notification_Mode_All": "Jokainen maininta/SV",
|
||||||
|
"Email_Notification_Mode_Disabled": "Ei käytössä",
|
||||||
|
"Email_or_password_field_is_empty": "Sähköposti- tai salasanakenttä on tyhjä",
|
||||||
|
"Email": "Sähköposti",
|
||||||
|
"email": "sähköposti",
|
||||||
|
"Empty_title": "Tyhjä otsikko",
|
||||||
|
"Enable_Auto_Translate": "Ota käyttöön automaattikäännös",
|
||||||
|
"Enable_notifications": "Ota käyttöön ilmoitukset",
|
||||||
|
"Encrypted": "Salattu",
|
||||||
|
"Encrypted_message": "Salattu viesti",
|
||||||
|
"Enter_Your_E2E_Password": "Anna täyden salauksen salasanasi",
|
||||||
|
"Enter_Your_Encryption_Password_desc1": "Näin pääset käyttämään salattuja yksityisiä ryhmiäsi ja suoria viestejäsi.",
|
||||||
|
"Enter_Your_Encryption_Password_desc2": "Sinun on annettava viestien salauksen / salauksen purkamisen salasana kaikkialla, missä käytät keskustelua.",
|
||||||
|
"Encryption_error_title": "Salauksen salasanasi näyttää väärältä",
|
||||||
|
"Encryption_error_desc": "Tuotavan salausavaimesi salausta ei voitu purkaa.",
|
||||||
|
"Everyone_can_access_this_channel": "Kaikilla on pääsy tälle kanavalle",
|
||||||
|
"Everyone_can_access_this_team": "Kaikilla on pääsy tähän tiimiin",
|
||||||
|
"Error_uploading": "Virhe ladattaessa",
|
||||||
|
"Expiration_Days": "Vanheneminen (päivää)",
|
||||||
|
"Favorites": "Suosikit",
|
||||||
|
"Files": "Tiedostot",
|
||||||
|
"File_description": "Tiedoston kuvaus",
|
||||||
|
"File_name": "Tiedostonimi",
|
||||||
|
"Finish_recording": "Lopeta tallennus",
|
||||||
|
"Following_thread": "Seurataan ketjua",
|
||||||
|
"For_your_security_you_must_enter_your_current_password_to_continue": "Jatka antamalla nykyinen salasanasi turvallisuussyistä",
|
||||||
|
"Forgot_password_If_this_email_is_registered": "Jos tämä sähköpostiosoite on rekisteröity, lähetämme salasanan nollausohjeet. Jos et saa sähköpostia pian, palaa ja yritä uudelleen.",
|
||||||
|
"Forgot_password": "Unohditko salasanasi?",
|
||||||
|
"Forgot_Password": "Unohtunut salasana",
|
||||||
|
"Forward": "Välitä",
|
||||||
|
"Forward_Chat": "Välitä keskustelu",
|
||||||
|
"Forward_to_department": "Välitä osastolle",
|
||||||
|
"Forward_to_user": "Välitä käyttäjälle",
|
||||||
|
"Full_table": "Näytä koko taulukko napsauttamalla",
|
||||||
|
"Generate_New_Link": "Luo uusi linkki",
|
||||||
|
"Get_link": "Hanki linkki",
|
||||||
|
"User_joined_the_channel": "liittyi kanavalle",
|
||||||
|
"User_joined_the_conversation": "liittyi keskusteluun",
|
||||||
|
"User_joined_the_team": "liittyi tähän tiimiin",
|
||||||
|
"User_left_this_channel": "poistui kanavalta",
|
||||||
|
"Has_left_the_team": "on poistunut tiimistä",
|
||||||
|
"Hide_System_Messages": "Piilota järjestelmäilmoitukset",
|
||||||
|
"Hide_type_messages": "Piilota \"{{type}}\"-viestit",
|
||||||
|
"How_It_Works": "Toimintatapa",
|
||||||
|
"Message_HideType_uj": "Käyttäjän liittyminen",
|
||||||
|
"Message_HideType_ul": "Käyttäjän poistuminen",
|
||||||
|
"Message_HideType_ru": "Käyttäjä poistettu",
|
||||||
|
"Message_HideType_au": "Käyttäjä lisätty",
|
||||||
|
"Message_HideType_mute_unmute": "Käyttäjä mykistetty / mykistys poistettu",
|
||||||
|
"Message_HideType_r": "Huoneen nimi vaihdettu",
|
||||||
|
"Message_HideType_ut": "Käyttäjä liittyi keskusteluun",
|
||||||
|
"Message_HideType_wm": "Tervetuloa",
|
||||||
|
"Message_HideType_rm": "Viesti poistettu",
|
||||||
|
"Message_HideType_subscription_role_added": "Annettiin rooli",
|
||||||
|
"Message_HideType_subscription_role_removed": "Rooli ei enää määritetty",
|
||||||
|
"Message_HideType_room_archived": "Huone arkistoitu",
|
||||||
|
"Message_HideType_room_unarchived": "Huone palautettu arkistosta",
|
||||||
|
"I_Saved_My_E2E_Password": "Tallensin täyden salauksen salasanani",
|
||||||
|
"IP": "IP",
|
||||||
|
"In_app": "Sovelluksessa",
|
||||||
|
"In_App_And_Desktop": "Sovelluksessa ja työpöydällä",
|
||||||
|
"In_App_and_Desktop_Alert_info": "Näyttää bannerin näytön yläreunassa, kun sovellus on avoinna, ja näyttää ilmoituksen työpöydällä",
|
||||||
|
"Invisible": "Näkymätön",
|
||||||
|
"Invite": "Kutsu",
|
||||||
|
"is_a_valid_RocketChat_instance": "on kelvollinen Rocket.Chat-esiintymä",
|
||||||
|
"is_not_a_valid_RocketChat_instance": "ei ole kelvollinen Rocket.Chat-esiintymä",
|
||||||
|
"is_typing": "kirjoittaa",
|
||||||
|
"Invalid_or_expired_invite_token": "Virheellinen tai vanhentunut kutsutunnus",
|
||||||
|
"Invalid_server_version": "Palvelin, johon yrität muodostaa yhteyttä, käyttää versiota, jota sovellus ei enää tue: {{currentVersion}}.\n\nEdellytämme versiota {{minVersion}}",
|
||||||
|
"Invite_Link": "Kutsulinkki",
|
||||||
|
"Invite_users": "Kutsu käyttäjiä",
|
||||||
|
"Join": "Liity",
|
||||||
|
"Join_Code": "Liittymiskoodi",
|
||||||
|
"Insert_Join_Code": "Lisää liittymiskoodi",
|
||||||
|
"Join_our_open_workspace": "Liity avoimeen työtilaamme",
|
||||||
|
"Join_your_workspace": "Liity työtilaasi",
|
||||||
|
"Just_invited_people_can_access_this_channel": "Vain kutsutut ihmiset voivat käyttää tätä kanavaa",
|
||||||
|
"Just_invited_people_can_access_this_team": "Vain kutsutut ihmiset voivat käyttää tätä tiimiä",
|
||||||
|
"Language": "Kieli",
|
||||||
|
"last_message": "viimeinen viesti",
|
||||||
|
"Leave_channel": "Poistu kanavalta",
|
||||||
|
"leaving_room": "poistuu huoneesta",
|
||||||
|
"Leave": "Poistu",
|
||||||
|
"leave": "poistu",
|
||||||
|
"Legal": "Oikeudellinen",
|
||||||
|
"Light": "Vaalea",
|
||||||
|
"License": "Käyttöoikeus",
|
||||||
|
"Livechat": "Livechat",
|
||||||
|
"Livechat_edit": "Livechat-muokkaus",
|
||||||
|
"Livechat_transfer_return_to_the_queue": "palautti keskustelun jonoon",
|
||||||
|
"Login": "Kirjaudu",
|
||||||
|
"Login_error": "Tunnistetietojasi ei hyväksytty! Yritä uudelleen.",
|
||||||
|
"Login_with": "Kirjaudu:",
|
||||||
|
"Logging_out": "Kirjaudutaan ulos.",
|
||||||
|
"Logout": "Kirjaudu ulos",
|
||||||
|
"Max_number_of_uses": "Käyttökertojen enimmäismäärä",
|
||||||
|
"Max_number_of_users_allowed_is_number": "Suurin sallittu käyttäjämäärä on {{maxUsers}}",
|
||||||
|
"members": "jäsentä",
|
||||||
|
"Members": "Jäsenet",
|
||||||
|
"Mentioned_Messages": "Mainitut viestit",
|
||||||
|
"mentioned": "mainitsi",
|
||||||
|
"Mentions": "Maininnat",
|
||||||
|
"Message_accessibility": "Viesti käyttäjältä {{user}} klo {{time}}: {{message}}",
|
||||||
|
"Message_actions": "Viestitoimet",
|
||||||
|
"Message_pinned": "Viesti kiinnitetty",
|
||||||
|
"Message_removed": "viesti poistettu",
|
||||||
|
"Message_starred": "Viesti merkitty tähdellä",
|
||||||
|
"Message_unstarred": "Viestin tähtimerkintä poistettu",
|
||||||
|
"message": "viesti",
|
||||||
|
"messages": "viestiä",
|
||||||
|
"Message": "Viesti",
|
||||||
|
"Messages": "Viestit",
|
||||||
|
"Message_Reported": "Viestistä ilmoitettu",
|
||||||
|
"Microphone_Permission_Message": "Rocket.Chat tarvitsee mikrofonin käyttöoikeuden, jotta voit lähettää ääniviestejä.",
|
||||||
|
"Microphone_Permission": "Mikrofonin oikeus",
|
||||||
|
"Mute": "Mykistä",
|
||||||
|
"muted": "mykistetty",
|
||||||
|
"My_servers": "Omat palvelimet",
|
||||||
|
"N_people_reacted": "{{n}} henkilöä reagoi",
|
||||||
|
"N_users": "{{n}} käyttäjää",
|
||||||
|
"N_channels": "{{n}} kanavaa",
|
||||||
|
"Name": "Nimi",
|
||||||
|
"Never": "Ei koskaan",
|
||||||
|
"New_chat_transfer": "Uuden keskustelun siirto: {{agent}} palautti keskustelun jonoon",
|
||||||
|
"New_Message": "Uusi viesti",
|
||||||
|
"New_Password": "Uusi salasana",
|
||||||
|
"New_Server": "Uusi palvelin",
|
||||||
|
"Next": "Seuraava",
|
||||||
|
"No_files": "Ei tiedostoja",
|
||||||
|
"No_limit": "Ei rajoitusta",
|
||||||
|
"No_mentioned_messages": "Ei mainittuja viestejä",
|
||||||
|
"No_pinned_messages": "Ei kiinnitettyjä viestejä",
|
||||||
|
"No_results_found": "Tuloksia ei löydy",
|
||||||
|
"No_members_found": "Jäseniä ei löydy",
|
||||||
|
"No_starred_messages": "Ei tähdellä merkittyjä viestejä",
|
||||||
|
"No_thread_messages": "Ei ketjuviestejä",
|
||||||
|
"No_label_provided": "Ei merkintää {{label}} provided.",
|
||||||
|
"No_Message": "Ei viestiä",
|
||||||
|
"No_messages_yet": "Ei vielä viestejä",
|
||||||
|
"No_Reactions": "Ei reaktioita",
|
||||||
|
"No_Read_Receipts": "Ei lukukuittauksia",
|
||||||
|
"Not_logged": "Ei kirjautunut",
|
||||||
|
"Not_RC_Server": "Tämä ei ole Rocket.Chat-palvelin.\n{{contact}}",
|
||||||
|
"Nothing": "Ei mitään",
|
||||||
|
"Nothing_to_save": "Ei tallennettavaa!",
|
||||||
|
"Notify_active_in_this_room": "Ilmoita tämän huoneen aktiivisille käyttäjille",
|
||||||
|
"Notify_all_in_this_room": "Ilmoita kaikille tässä huoneessa",
|
||||||
|
"Notifications": "Ilmoitukset",
|
||||||
|
"Notification_Duration": "Ilmoituksen kesto",
|
||||||
|
"Notification_Preferences": "Ilmoitusasetukset",
|
||||||
|
"No_available_agents_to_transfer": "Ei vapaita agentteja siirrettäviksi",
|
||||||
|
"Offline": "Offline",
|
||||||
|
"Oops": "Oho!",
|
||||||
|
"Omnichannel": "Omnichannel",
|
||||||
|
"Omnichannel_enable_alert": "Et ole saavutettavissa Omnichannelissa. Haluatko olla saavutettavissa?",
|
||||||
|
"Onboarding_description": "Työtila on tiimisi tai organisaatiosi tila yhteistyölle. Pyydä työtilan järjestelmänvalvojalta osoite, jotta voit liittyä työtilaan tai luoda sellaisen tiimillesi.",
|
||||||
|
"Onboarding_join_workspace": "Liity työtilaan",
|
||||||
|
"Onboarding_subtitle": "Enemmän kuin ryhmäyhteistyötä",
|
||||||
|
"Onboarding_title": "Tervetuloa Rocket.Chatiin",
|
||||||
|
"Onboarding_join_open_description": "Liity avoimeen työtilaamme keskustelemaan Rocket.Chat-tiimin ja -yhteisön kanssa.",
|
||||||
|
"Onboarding_agree_terms": "Jatkamalla hyväksyt Rocket.Chatin",
|
||||||
|
"Onboarding_less_options": "Vähemmän vaihtoehtoja",
|
||||||
|
"Onboarding_more_options": "Enemmän vaihtoehtoja",
|
||||||
|
"Online": "Online",
|
||||||
|
"Only_authorized_users_can_write_new_messages": "Vain valtuutetut käyttäjät voivat kirjoittaa uusia viestejä",
|
||||||
|
"Open_emoji_selector": "Avaa emojien valitsin",
|
||||||
|
"Open_Source_Communication": "Avoimen lähdekoodin viestintä",
|
||||||
|
"Open_your_authentication_app_and_enter_the_code": "Avaa todennussovellus ja anna koodi.",
|
||||||
|
"OR": "TAI",
|
||||||
|
"OS": "Käyttöjärjestelmä",
|
||||||
|
"Overwrites_the_server_configuration_and_use_room_config": "Korvaa palvelimen määritykset ja käyttää huoneen määrityksiä",
|
||||||
|
"Password": "Salasana",
|
||||||
|
"Parent_channel_or_group": "Pääkanava tai -ryhmä",
|
||||||
|
"Permalink_copied_to_clipboard": "Pysyvä linkki kopioitu leikepöydälle!",
|
||||||
|
"Phone": "Puhelin",
|
||||||
|
"Pin": "Kiinnitä",
|
||||||
|
"Pinned_Messages": "Kiinnitetyt viestit",
|
||||||
|
"pinned": "kiinnitetty",
|
||||||
|
"Pinned": "Kiinnitetty",
|
||||||
|
"Please_add_a_comment": "Lisää kommentti",
|
||||||
|
"Please_enter_your_password": "Anna salasana",
|
||||||
|
"Please_wait": "Odota.",
|
||||||
|
"Preferences": "Asetukset",
|
||||||
|
"Preferences_saved": "Asetukset tallennettu!",
|
||||||
|
"Privacy_Policy": "Tietosuojakäytäntö",
|
||||||
|
"Private": "Yksityinen",
|
||||||
|
"Processing": "Käsitellään...",
|
||||||
|
"Profile_saved_successfully": "Profiili on tallennettu!",
|
||||||
|
"Profile": "Profiili",
|
||||||
|
"Public_Channel": "Julkinen kanava",
|
||||||
|
"Public": "Julkinen",
|
||||||
|
"Push_Notifications": "Push-ilmoitukset",
|
||||||
|
"Push_Notifications_Alert_Info": "Saat näitä ilmoituksia, kun sovellus ei ole auki",
|
||||||
|
"Quote": "Lainaus",
|
||||||
|
"Reactions_are_disabled": "Reaktiot eivät ole käytössä",
|
||||||
|
"Reactions_are_enabled": "Reaktiot ovat käytössä",
|
||||||
|
"Reactions": "Reaktiot",
|
||||||
|
"Read_External_Permission_Message": "Rocket.Chat tarvitsee pääsyn laitteesi valokuviin, mediaan ja tiedostoihin",
|
||||||
|
"Read_External_Permission": "Median lukuoikeus",
|
||||||
|
"Read_Only": "Vain luku",
|
||||||
|
"Read_Receipt": "Lukukuittaus",
|
||||||
|
"Receive_Group_Mentions": "Vastaanota ryhmämainintoja",
|
||||||
|
"Receive_Group_Mentions_Info": "Vastaanota @all- ja @here-maininnat",
|
||||||
|
"Register": "Rekisteröi",
|
||||||
|
"Repeat_Password": "Toista salasana",
|
||||||
|
"Replied_on": "Vastasi:",
|
||||||
|
"replies": "vastausta",
|
||||||
|
"reply": "vastaus",
|
||||||
|
"Reply": "Vastaa",
|
||||||
|
"Report": "Ilmoita",
|
||||||
|
"Receive_Notification": "Vastaanota ilmoitus",
|
||||||
|
"Receive_notifications_from": "Vastaanota ilmoitukset käyttäjältä {{name}}",
|
||||||
|
"Resend": "Lähetä uudelleen",
|
||||||
|
"Reset_password": "Nollaa salasana",
|
||||||
|
"resetting_password": "nollaa salasanaa",
|
||||||
|
"RESET": "NOLLAA",
|
||||||
|
"Return_to_waiting_line": "Palaa jonoon",
|
||||||
|
"Review_app_title": "Pidätkö tästä sovelluksesta?",
|
||||||
|
"Review_app_desc": "Anna meille 5 tähteä: {{store}}",
|
||||||
|
"Review_app_yes": "Selvä!",
|
||||||
|
"Review_app_no": "Ei",
|
||||||
|
"Review_app_later": "Ehkä myöhemmin",
|
||||||
|
"Review_app_unable_store": "Ei voida avata: {{store}}",
|
||||||
|
"Review_this_app": "Arvioi tämä sovellus",
|
||||||
|
"Remove": "Poista",
|
||||||
|
"remove": "poista",
|
||||||
|
"Roles": "Roolit",
|
||||||
|
"Room_actions": "Huoneen toimet",
|
||||||
|
"Room_changed_announcement": "Huoneen ilmoitukseksi vaihdettu: {{announcement}} käyttäjä: {{userBy}}",
|
||||||
|
"room_avatar_changed": "vaihtoi huoneen avatarin",
|
||||||
|
"Room_changed_description": "Huoneen kuvaukseksi vaihdettu: {{description}} käyttäjä: {{userBy}}",
|
||||||
|
"changed_room_description": "vaihtoi huoneen kuvaukseksi: {{description}}",
|
||||||
|
"changed_room_announcement": "vaihtoi huoneen ilmoitukseksi: {{announcement}}",
|
||||||
|
"room_changed_type": "vaihtoi huoneen tyypiksi {{type}}",
|
||||||
|
"room_changed_topic_to": "vaihtoi huoneen aiheeksi: {{topic}}",
|
||||||
|
"Room_Files": "Huoneen tiedostot",
|
||||||
|
"Room_Info_Edit": "Huoneen tietojen muokkaus",
|
||||||
|
"Room_Info": "Huoneen tiedot",
|
||||||
|
"Room_Members": "Huoneen jäsenet",
|
||||||
|
"Room_name_changed_to": "vaihtoi huoneen nimeksi: {{name}}",
|
||||||
|
"room_disallowed_reactions": "kielsi reaktiot",
|
||||||
|
"room_allowed_reactions": "salli reaktiot",
|
||||||
|
"room_removed_read_only_permission": "poisti vain luku -oikeuden",
|
||||||
|
"room_set_read_only_permission": "asetti huoneen vain luku -tilaan",
|
||||||
|
"SAVE": "TALLENNA",
|
||||||
|
"Save_Changes": "Tallenna muutokset",
|
||||||
|
"Save": "Tallenna",
|
||||||
|
"Saved": "Tallennettu",
|
||||||
|
"saving_preferences": "tallentaa asetuksia",
|
||||||
|
"saving_profile": "tallentaa profiilia",
|
||||||
|
"saving_settings": "tallentaa asetuksia",
|
||||||
|
"saved_to_gallery": "Tallennettu galleriaan",
|
||||||
|
"Save_Your_E2E_Password": "Tallenna täyen salauksen salasanasi",
|
||||||
|
"Save_Your_Encryption_Password": "Tallenna salauksen salasanasi",
|
||||||
|
"Save_Your_Encryption_Password_warning": "Tätä salasanaa ei tallenneta mihinkään, joten tallenna se huolellisesti muualle.",
|
||||||
|
"Save_Your_Encryption_Password_info": "Huomioi, että jos kadotat salasanasi, sitä ei voi palauttaa etkä pääse enää viesteihisi.",
|
||||||
|
"Search_Messages": "Hae viestejä",
|
||||||
|
"Search": "Haku",
|
||||||
|
"Search_by": "Hakuperuste",
|
||||||
|
"Search_emoji": "Hae emojia",
|
||||||
|
"Search_global_users": "Hae käyttäjiä kaikkialta",
|
||||||
|
"Search_global_users_description": "Jos otat tämän käyttöön, voit etsiä käyttäjiä muista yrityksistä tai palvelimista.",
|
||||||
|
"Seconds": "{{second}} sekuntia",
|
||||||
|
"Security_and_privacy": "Turvallisuus ja yksityisyys",
|
||||||
|
"Select_Avatar": "Valitse avatar",
|
||||||
|
"Select_Server": "Valitse palvelin",
|
||||||
|
"Select_Users": "Valitse käyttäjät",
|
||||||
|
"Select_a_Channel": "Valitse kanava",
|
||||||
|
"Select_a_Department": "Valitse osasto",
|
||||||
|
"Select_an_option": "Valitse vaihtoehto",
|
||||||
|
"Select_a_User": "Valitse käyttäjä",
|
||||||
|
"Send": "Lähetä",
|
||||||
|
"Send_audio_message": "Lähetä ääniviesti",
|
||||||
|
"Send_crash_report": "Lähetä kaatumisraportti",
|
||||||
|
"Send_message": "Lähetä viesti",
|
||||||
|
"Send_me_the_code_again": "Lähetä koodi uudelleen",
|
||||||
|
"Send_to": "Lähetä kohteeseen...",
|
||||||
|
"Sending_to": "Lähetetään kohteeseen",
|
||||||
|
"Sent_an_attachment": "Lähetettiin liite",
|
||||||
|
"Server": "Palvelin",
|
||||||
|
"Servers": "Palvelimet",
|
||||||
|
"Server_version": "Palvelimen versio: {{version}}",
|
||||||
|
"Set_username_subtitle": "Käyttäjätunnuksen avulla muut voivat mainita sinut viesteissä",
|
||||||
|
"Set_custom_status": "Aseta mukautettu tila",
|
||||||
|
"Set_status": "Aseta tila",
|
||||||
|
"Status_saved_successfully": "Tila on tallennettu!",
|
||||||
|
"Settings": "Asetukset",
|
||||||
|
"Settings_succesfully_changed": "Asetukset on muutettu!",
|
||||||
|
"Share": "Jaa",
|
||||||
|
"Share_Link": "Jaa linkki",
|
||||||
|
"Share_this_app": "Jaa tämä sovellus",
|
||||||
|
"Show_more": "Näytä lisää...",
|
||||||
|
"Sign_in_your_server": "Kirjaudu palvelimeesi",
|
||||||
|
"Sign_Up": "Rekisteröidy",
|
||||||
|
"Some_field_is_invalid_or_empty": "Jokin kenttä on virheellinen tai tyhjä",
|
||||||
|
"Sound": "Ääni",
|
||||||
|
"Star_room": "Tähdellinen huone",
|
||||||
|
"Star": "Tähti",
|
||||||
|
"Starred_Messages": "Tähdellä merkityt viestit",
|
||||||
|
"starred": "tähdellä merkittyä",
|
||||||
|
"Starred": "Tähdellä merkityt",
|
||||||
|
"Start_of_conversation": "Keskustelun alku",
|
||||||
|
"Start_a_Discussion": "Aloita keskustelu",
|
||||||
|
"Started_discussion": "Aloitettiin keskustelu:",
|
||||||
|
"Started_call": "Puhelun aloitti {{userBy}}",
|
||||||
|
"Submit": "Lähetä",
|
||||||
|
"Table": "Taulukko",
|
||||||
|
"Tags": "Tunnisteet",
|
||||||
|
"Take_a_photo": "Ota valokuva",
|
||||||
|
"Take_a_video": "Kuvaa video",
|
||||||
|
"Take_it": "Ota!",
|
||||||
|
"tap_to_change_status": "vaihda tilaa napauttamalla",
|
||||||
|
"Tap_to_view_servers_list": "Näytä palvelinluettelo napauttamalla",
|
||||||
|
"Terms_of_Service": "Käyttöehdot",
|
||||||
|
"Theme": "Teema",
|
||||||
|
"The_user_wont_be_able_to_type_in_roomName": "Käyttäjä ei voi kirjoittaa huoneessa {{roomName}}",
|
||||||
|
"The_user_will_be_able_to_type_in_roomName": "Käyttäjä voi kirjoittaa huoneessa {{roomName}}",
|
||||||
|
"There_was_an_error_while_action": "Virhe toiminnon {{action}} aikana!",
|
||||||
|
"This_room_is_blocked": "Huone on estetty",
|
||||||
|
"This_room_is_read_only": "Huone on vain luku -tilassa",
|
||||||
|
"Thread": "Ketju",
|
||||||
|
"Threads": "Ketjut",
|
||||||
|
"Timezone": "Aikavyöhyke",
|
||||||
|
"To": "Osoitteeseen",
|
||||||
|
"topic": "aihe",
|
||||||
|
"Topic": "Aihe",
|
||||||
|
"Translate": "Käännä",
|
||||||
|
"Try_again": "Yritä uudelleen",
|
||||||
|
"Two_Factor_Authentication": "Kaksivaiheinen tunnistautuminen",
|
||||||
|
"Type_the_channel_name_here": "Kirjoita kanavan nimi tähän",
|
||||||
|
"unarchive": "palauta arkistosta",
|
||||||
|
"UNARCHIVE": "PALAUTA ARKISTOSTA",
|
||||||
|
"Unblock_user": "Poista käyttäjän esto",
|
||||||
|
"Unfollowed_thread": "Lopetettiin ketjun seuraaminen",
|
||||||
|
"Unmute": "Mykistys poistettu",
|
||||||
|
"unmuted": "poisti mykistyksen",
|
||||||
|
"Unpin": "Poista kiinnitys",
|
||||||
|
"unread_messages": "lukematonta",
|
||||||
|
"Unread": "Lukemattomat",
|
||||||
|
"Unread_on_top": "Lukemattomat ylinnä",
|
||||||
|
"Unstar": "Poista tähti",
|
||||||
|
"Unsupported_system_message": "Ei tuettu järjestelmäilmoitus",
|
||||||
|
"Updating": "Päivitetään...",
|
||||||
|
"Uploading": "Ladataan",
|
||||||
|
"FileUpload_Error": "Tiedoston latausvirhe",
|
||||||
|
"Upload_in_progress": "Lataus käynnissä",
|
||||||
|
"Upload_file_question_mark": "Ladataanko tiedosto?",
|
||||||
|
"User": "Käyttäjä",
|
||||||
|
"Users": "Käyttäjät",
|
||||||
|
"User_added_to": "lisäsi käyttäjän {{userAdded}}",
|
||||||
|
"User_Info": "Käyttäjän tiedot",
|
||||||
|
"User_has_been_key": "Käyttäjä on {{key}}",
|
||||||
|
"User_is_no_longer_role_by_": "{{user}} ei ole enää {{role}}, muutti {{userBy}}",
|
||||||
|
"User_has_been_muted": "mykisti käyttäjän {{userMuted}}",
|
||||||
|
"User_has_been_removed": "poisti käyttäjän {{userRemoved}}",
|
||||||
|
"User_sent_an_attachment": "{{user}} lähetti liitteen",
|
||||||
|
"User_has_been_unmuted": "poisti käyttäjän {{userUnmuted}} mykistyksen",
|
||||||
|
"Defined_user_as_role": "määritti käyttäjän {{user}} rooliin {{role}}",
|
||||||
|
"Removed_user_as_role": "poisti käyttäjän {{user}} roolista {{role}}",
|
||||||
|
"Username_is_empty": "Käyttäjätunnus on tyhjä",
|
||||||
|
"Username": "Käyttäjätunnus",
|
||||||
|
"Username_or_email": "Sähköpostiosoite tai käyttäjätunnus",
|
||||||
|
"Uses_server_configuration": "Käyttää palvelimen määrityksiä",
|
||||||
|
"Validating": "Vahvistetaan",
|
||||||
|
"Registration_Succeeded": "Rekisteröinti onnistui!",
|
||||||
|
"Verify": "Varmista",
|
||||||
|
"Verify_email_title": "Rekisteröinti onnistui!",
|
||||||
|
"Verify_email_desc": "Lähetimme rekisteröitymisvahvistuksen sähköpostiisi. Jos et saa sähköpostia pian, yritä uudelleen.",
|
||||||
|
"Verify_your_email_for_the_code_we_sent": "Vahvista sähköpostiosoitteesi lähettämällämme koodilla",
|
||||||
|
"Video_call": "Videopuhelu",
|
||||||
|
"View_Original": "Näytä alkuperäinen",
|
||||||
|
"Voice_call": "Äänipuhelu",
|
||||||
|
"Waiting_for_network": "Odotetaan verkkoa...",
|
||||||
|
"Websocket_disabled": "Websocket ei ole käytössä tässä palvelimessa.\n{{contact}}",
|
||||||
|
"Welcome": "Tervetuloa",
|
||||||
|
"What_are_you_doing_right_now": "Mitä teet juuri nyt?",
|
||||||
|
"Whats_your_2fa": "Mikä on 2FA-koodisi?",
|
||||||
|
"Without_Servers": "Ilman palvelimia",
|
||||||
|
"Workspaces": "Työtilat",
|
||||||
|
"Would_you_like_to_return_the_inquiry": "Haluatko palauttaa kyselyn?",
|
||||||
|
"Write_External_Permission_Message": "Rocket.Chat tarvitsee gallerian käyttöoikeuden, jotta voit tallentaa kuvia.",
|
||||||
|
"Write_External_Permission": "Gallerian käyttöoikeus",
|
||||||
|
"Yes": "Kyllä",
|
||||||
|
"Yes_action_it": "Kyllä, {{action}} se!",
|
||||||
|
"Yesterday": "Eilen",
|
||||||
|
"You_are_in_preview_mode": "Olet esikatselutilassa",
|
||||||
|
"You_are_offline": "Olet offline-tilassa",
|
||||||
|
"You_can_search_using_RegExp_eg": "Voit käyttää säännöllisiä lausekkeita, esim. `/^teksti$/i`",
|
||||||
|
"You_colon": "Sinä:",
|
||||||
|
"you_were_mentioned": "sinut mainittiin",
|
||||||
|
"You_were_removed_from_channel": "Sinut on poistettu kanavalta {{channel}}",
|
||||||
|
"you": "sinä",
|
||||||
|
"You": "Sinä",
|
||||||
|
"Logged_out_by_server": "Palvelin on kirjannut sinut ulos. Kirjaudu uudelleen.",
|
||||||
|
"Token_expired": "Istuntosi on vanhentunut. Kirjaudu uudelleen.",
|
||||||
|
"You_need_to_access_at_least_one_RocketChat_server_to_share_something": "Tarvitset pääsyn vähintään Rocket.Chat-palvelimeen jakamista varten.",
|
||||||
|
"You_need_to_verifiy_your_email_address_to_get_notications": "Vahvista sähköpostiosoitteesi, jotta saat ilmoituksia",
|
||||||
|
"Your_certificate": "Varmenteesi",
|
||||||
|
"Your_invite_link_will_expire_after__usesLeft__uses": "Kutsulinkkisi vanhenee {{usesLeft}} käyttökerran jälkeen.",
|
||||||
|
"Your_invite_link_will_expire_on__date__or_after__usesLeft__uses": "Kutsulinkkisi vanhenee {{date}} tai {{usesLeft}} käyttökerran jälkeen.",
|
||||||
|
"Your_invite_link_will_expire_on__date__": "Kutsulinkkisi vanhenee {{date}}.",
|
||||||
|
"Your_invite_link_will_never_expire": "Kutsulinkkisi ei vanhene.",
|
||||||
|
"Your_workspace": "Työtilasi",
|
||||||
|
"Your_password_is": "Salasanasi on",
|
||||||
|
"Version_no": "Versio: {{version}}",
|
||||||
|
"You_will_not_be_able_to_recover_this_message": "Tätä viestiä ei voi palauttaa!",
|
||||||
|
"You_will_unset_a_certificate_for_this_server": "Poistat tämän palvelimen varmenteen asetuksen",
|
||||||
|
"Change_Language": "Vaihda kieltä",
|
||||||
|
"Crash_report_disclaimer": "Keskustelujesi sisältöä ei seurata. Kaatumisraportti ja analytiikkatapahtumat sisältävät vain olennaiset tiedot, jotta pystymme tunnistamaan ja korjaamaan ongelmat.",
|
||||||
|
"Type_message": "Kirjoita viesti",
|
||||||
|
"Room_search": "Huonehaku",
|
||||||
|
"Room_selection": "Huoneen valinta 1...9",
|
||||||
|
"Next_room": "Seuraava huone",
|
||||||
|
"Previous_room": "Edellinen huone",
|
||||||
|
"New_room": "Uusi huone",
|
||||||
|
"Upload_room": "Lataa huoneeseen",
|
||||||
|
"Search_messages": "Hae viestejä",
|
||||||
|
"Scroll_messages": "Vieritä viestejä",
|
||||||
|
"Reply_latest": "Vastaa uusimpaan",
|
||||||
|
"Reply_in_Thread": "Vastaa viestiketjussa",
|
||||||
|
"Server_selection": "Palvelimen valinta",
|
||||||
|
"Server_selection_numbers": "Palvelimen valinta 1...9",
|
||||||
|
"Add_server": "Lisää palvelin",
|
||||||
|
"New_line": "Uusi rivi",
|
||||||
|
"You_will_be_logged_out_of_this_application": "Sinut kirjataan ulos tästä sovelluksesta.",
|
||||||
|
"Clear": "Tyhjennä",
|
||||||
|
"This_will_clear_all_your_offline_data": "Tämä poistaa kaikki offline-tietosi.",
|
||||||
|
"This_will_remove_all_data_from_this_server": "Tämä poistaa kaikki tiedot tästä palvelimesta.",
|
||||||
|
"Mark_unread": "Merkitse lukemattomaksi",
|
||||||
|
"Wait_activation_warning": "Ennen kuin voit kirjautua, järjestelmänvalvojan on aktivoitava tilisi manuaalisesti.",
|
||||||
|
"Screen_lock": "Näytön lukitus",
|
||||||
|
"Local_authentication_biometry_title": "Todenna",
|
||||||
|
"Local_authentication_biometry_fallback": "Käytä salasanaa",
|
||||||
|
"Local_authentication_unlock_option": "Avaa lukitus salasanalla",
|
||||||
|
"Local_authentication_change_passcode": "Vaihda salasana",
|
||||||
|
"Local_authentication_info": "Huomautus: jos unohdat salasanan, sinun on poistettava sovellus ja asennettava se uudelleen.",
|
||||||
|
"Local_authentication_facial_recognition": "kasvojentunnistus",
|
||||||
|
"Local_authentication_fingerprint": "sormenjälki",
|
||||||
|
"Local_authentication_unlock_with_label": "Avaa lukitus: {{label}}",
|
||||||
|
"Local_authentication_auto_lock_60": "1 minuutin kuluttua",
|
||||||
|
"Local_authentication_auto_lock_300": "5 minuutin kuluttua",
|
||||||
|
"Local_authentication_auto_lock_900": "15 minuutin kuluttua",
|
||||||
|
"Local_authentication_auto_lock_1800": "30 minuutin kuluttua",
|
||||||
|
"Local_authentication_auto_lock_3600": "1 tunnin kuluttua",
|
||||||
|
"Passcode_enter_title": "Anna salasanasi",
|
||||||
|
"Passcode_choose_title": "Valitse uusi salasana",
|
||||||
|
"Passcode_choose_confirm_title": "Vahvista uusi salasana",
|
||||||
|
"Passcode_choose_error": "Salasanat eivät täsmää. Yritä uudelleen.",
|
||||||
|
"Passcode_choose_force_set": "Järjestelmänvalvoja edellyttää salasanaa",
|
||||||
|
"Passcode_app_locked_title": "Sovellus lukittu",
|
||||||
|
"Passcode_app_locked_subtitle": "Yritä uudelleen {{timeLeft}} sekunnin kuluttua",
|
||||||
|
"After_seconds_set_by_admin": "{{seconds}} sekunnin kuluttua (järjestelmänvalvojan asettama)",
|
||||||
|
"Dont_activate": "Älä aktivoi nyt",
|
||||||
|
"Queued_chats": "Jonossa olevat keskustelut",
|
||||||
|
"Logout_from_other_logged_in_locations": "Kirjaa ulos muista sijainneista",
|
||||||
|
"You_will_be_logged_out_from_other_locations": "Sinut kirjataan ulos muista sijainneista.",
|
||||||
|
"Logged_out_of_other_clients_successfully": "Kirjattu ulos muissa asiakkaissa",
|
||||||
|
"Logout_failed": "Uloskirjaus epäonnistui!",
|
||||||
|
"Log_analytics_events": "Kirjaa analytiikkatapahtumat",
|
||||||
|
"E2E_encryption_change_password_title": "Vaihda salauksen salasana",
|
||||||
|
"E2E_encryption_change_password_description": "Nyt voit luoda salattuja yksityisiä ryhmiä ja suoria viestejä. Voit myös muuttaa nykyisiä yksityisiä ryhmiä tai suoria viestejä salatuksi. \nTämä on täysi salaus, joten viestiesi salaamiseen ja salaukseen purkuun käytettävää avainta ei tallenneta palvelimeen. Siksi sinun on tallennettava salasanasi turvalliseen paikkaan. Sinun on annettava se muissa laitteissa, joissa haluat käyttää täyttä salausta.",
|
||||||
|
"E2E_encryption_change_password_error": "Virhe vaihdettaessa täyden salauksen avaimen salasanaa!",
|
||||||
|
"E2E_encryption_change_password_success": "Täyden salauksen avaimen salasana on vaihdettu!",
|
||||||
|
"E2E_encryption_change_password_message": "Varmista, että olet tallentanut sen huolellisesti muualle.",
|
||||||
|
"E2E_encryption_change_password_confirmation": "Kyllä, vaihda se",
|
||||||
|
"E2E_encryption_reset_title": "Nollaa täyden salauksen avain",
|
||||||
|
"E2E_encryption_reset_description": "Tämä asetus poistaa nykyisen täyden salauksen avaimesi ja kirjaa sinut ulos. \nKun kirjaudut uudelleen sisään, Rocket.Chat luo sinulle uuden avaimen ja palauttaa pääsysi kaikkiin salattuihin huoneisiin, joissa on aktiivisia jäseniä. \nTäyden salauksen luonteen vuoksi Rocket.Chat ei pysty palauttamaan pääsyä salattuihin huoneisiin, joissa ei ole aktiivisia jäseniä.",
|
||||||
|
"E2E_encryption_reset_button": "Nollaa täyden salauksen avain",
|
||||||
|
"E2E_encryption_reset_error": "Virhe nollattaessa täyden salauksen avainta!",
|
||||||
|
"E2E_encryption_reset_message": "Sinut kirjataan ulos.",
|
||||||
|
"E2E_encryption_reset_confirmation": "Kyllä, nollaa se",
|
||||||
|
"Following": "Seurataan",
|
||||||
|
"Threads_displaying_all": "Näytetään kaikki",
|
||||||
|
"Threads_displaying_following": "Näytetään seuratut",
|
||||||
|
"Threads_displaying_unread": "Näytetään lukemattomat",
|
||||||
|
"No_threads": "Ei ketjuja",
|
||||||
|
"No_threads_following": "Et seuraa ketjuja",
|
||||||
|
"No_threads_unread": "Ei lukemattomia ketjuja",
|
||||||
|
"Messagebox_Send_to_channel": "Lähetä kanavalle",
|
||||||
|
"Leader": "Johtaja",
|
||||||
|
"Moderator": "Moderaattori",
|
||||||
|
"Owner": "Omistaja",
|
||||||
|
"Remove_from_room": "Poista huoneesta",
|
||||||
|
"Ignore": "Ohita",
|
||||||
|
"Unignore": "Kumoa ohitus",
|
||||||
|
"User_has_been_ignored": "Käyttäjä on ohitettu",
|
||||||
|
"User_has_been_unignored": "Käyttäjää ei enää ohiteta",
|
||||||
|
"User_has_been_removed_from_s": "Käyttäjä on poistettu kohteesta {{s}}",
|
||||||
|
"User__username__is_now_a_leader_of__room_name_": "Käyttäjä {{username}} on nyt huoneen {{room_name}} johtaja",
|
||||||
|
"User__username__is_now_a_moderator_of__room_name_": "Käyttäjä {{username}} on nyt huoneen {{room_name}} moderaattori",
|
||||||
|
"User__username__is_now_a_owner_of__room_name_": "Käyttäjä {{username}} on nyt huoneen {{room_name}} omistaja",
|
||||||
|
"User__username__removed_from__room_name__leaders": "Käyttäjä {{username}} poistettiin huoneen {{room_name}} johtajista",
|
||||||
|
"User__username__removed_from__room_name__moderators": "Käyttäjä {{username}} poistettiin huoneen {{room_name}} moderaattoreista",
|
||||||
|
"User__username__removed_from__room_name__owners": "Käyttäjä {{username}} poistettiin huoneen {{room_name}} omistajista",
|
||||||
|
"The_user_will_be_removed_from_s": "Käyttäjä poistetaan kohteesta {{s}}",
|
||||||
|
"Yes_remove_user": "Kyllä, poista käyttäjä!",
|
||||||
|
"Direct_message": "Suora viesti",
|
||||||
|
"Message_Ignored": "Viesti ohitettu. Näytä se napauttamalla.",
|
||||||
|
"Enter_workspace_URL": "Anna työtilan URL-osoite",
|
||||||
|
"Workspace_URL_Example": "Esim. yrityksesi.rocket.chat",
|
||||||
|
"Enabled_E2E_Encryption_for_this_room": "otti täyden salauksen käyttöön tässä huoneessa",
|
||||||
|
"Disabled_E2E_Encryption_for_this_room": "poisti täyden salauksen käytöstä tässä huoneessa",
|
||||||
|
"Teams": "Tiimit",
|
||||||
|
"No_team_channels_found": "Kanavia ei löydy",
|
||||||
|
"Team_not_found": "Tiimiä ei löydy",
|
||||||
|
"Create_Team": "Luo tiimi",
|
||||||
|
"Team_Name": "Tiimin nimi",
|
||||||
|
"creating_team": "luo tiimiä",
|
||||||
|
"team-name-already-exists": "Tiimi tällä nimellä on jo olemassa",
|
||||||
|
"Add_Channel_to_Team": "Lisää kanava tiimille",
|
||||||
|
"Left_The_Team_Successfully": "Poistuttiin tiimistä",
|
||||||
|
"Create_New": "Luo uusi",
|
||||||
|
"Add_Existing": "Lisää olemassa oleva",
|
||||||
|
"Add_Existing_Channel": "Lisää olemassa oleva kanava",
|
||||||
|
"Remove_from_Team": "Poista tiimistä",
|
||||||
|
"Auto-join": "Automaattinen liittyminen",
|
||||||
|
"Remove_Team_Room_Warning": "Haluatko poistaa tämän kanavan tiimiltä? Kanava siirretään takaisin työtilaan",
|
||||||
|
"Confirmation": "Vahvistus",
|
||||||
|
"invalid-room": "Virheellinen huone",
|
||||||
|
"You_are_leaving_the_team": "Poistut tiimistä {{team}}",
|
||||||
|
"Leave_Team": "Poistu tiimistä",
|
||||||
|
"Select_Team": "Valitse tiimi",
|
||||||
|
"Select_Team_Channels": "Valitse tiimin kanavat, joilta haluat poistua.",
|
||||||
|
"Cannot_leave": "Ei voi poistua",
|
||||||
|
"Cannot_remove": "Ei voi poistaa",
|
||||||
|
"Cannot_delete": "Ei voi poistaa",
|
||||||
|
"Last_owner_team_room": "Olet tämän kanavan viimeinen omistaja. Kun lähdet tiimistä, kanava säilyy tiimin sisällä, mutta hallinnoit sitä ulkopuolelta.",
|
||||||
|
"last-owner-can-not-be-removed": "Viimeistä omistajaa ei voi poistaa",
|
||||||
|
"Remove_User_Teams": "Valitse kanavat, joilta haluat poistaa käyttäjän.",
|
||||||
|
"Deleting_account": "Poistetaan tiliä",
|
||||||
|
"Delete_my_account": "Poista tilini",
|
||||||
|
"Delete_Team": "Poista tiimi",
|
||||||
|
"Select_channels_to_delete": "Tätä ei voi kumota. Kun poistat tiimin, kaikki keskustelusisältö ja määritykset poistetaan. \n\nValitse poistettavat kanavat. Säilyttämäsi kanavat ovat käytettävissä työtilassasi. Huomioi, että julkiset kanavat ovat edelleen julkisia ja näkyvissä kaikille.",
|
||||||
|
"You_are_deleting_the_team": "Olet poistamassa tämän tiimin.",
|
||||||
|
"Removing_user_from_this_team": "Poistat käyttäjää {{user}} tästä tiimistä",
|
||||||
|
"Remove_User_Team_Channels": "Valitse kanavat, joilta haluat poistaa käyttäjän.",
|
||||||
|
"Remove_Member": "Poista jäsen",
|
||||||
|
"leaving_team": "poistuu tiimistä",
|
||||||
|
"removing_team": "poistaa tiimistä",
|
||||||
|
"moving_channel_to_team": "siirtää kanavaa tiimille",
|
||||||
|
"deleting_team": "poistaa tiimiä",
|
||||||
|
"member-does-not-exist": "Jäsentä ei ole",
|
||||||
|
"Convert": "Muunna",
|
||||||
|
"Convert_to_Team": "Muunna tiimiksi",
|
||||||
|
"Convert_to_Team_Warning": "Muunnat tätä kanavaa tiimiksi. Kaikki jäsenet säilytetään.",
|
||||||
|
"Move_to_Team": "Siirrä tiimiin",
|
||||||
|
"Move_Channel_Paragraph": "Kanavan siirtäminen tiimiin tarkoittaa, että tämä kanava lisätään tiimin kontekstiin. Kaikki kanavan jäsenet, jotka eivät ole vastaavan tiimin jäseniä, pääsevät silti edelleen tälle kanavalle, mutta heitä ei lisätä tiimin jäseniksi. \n\nKanavan omistajat hoitavat edelleen kaiken kanavan hallinnan.\n\nTiimin jäsenillä ja jopa tiimin omistajilla, jotka eivät ole tämän kanavan jäseniä, ei ole pääsyä kanavan sisältöön. \n\nHuomioi, että tiimin omistaja voi poistaa jäseniä kanavalta.",
|
||||||
|
"Move_to_Team_Warning": "Nyt kun olet lukenut edellä olevat tätä toimintaa koskevat ohjeet, haluatko silti siirtää tämän kanavan valitulle tiimille?",
|
||||||
|
"Load_More": "Lataa lisää",
|
||||||
|
"Load_Newer": "Lataa uudemmat",
|
||||||
|
"Load_Older": "Lataa vanhemmat",
|
||||||
|
"room-name-already-exists": "Huoneen nimi on jo olemassa",
|
||||||
|
"error-team-creation": "Tiimin luontivirhe",
|
||||||
|
"unauthorized": "Valtuuttamaton",
|
||||||
|
"Left_The_Room_Successfully": "Poistuttiin huoneesta",
|
||||||
|
"Deleted_The_Team_Successfully": "Tiimi on poistettu",
|
||||||
|
"Deleted_The_Room_Successfully": "Huone on poistettu",
|
||||||
|
"Convert_to_Channel": "Muunna kanavaksi",
|
||||||
|
"Converting_Team_To_Channel": "Muunnetaan tiimiä kanavaksi",
|
||||||
|
"Select_Team_Channels_To_Delete": "Valitse poistettavat tiimin kanavat. Valitsematta jättämäsi kanavat siirretään työtilaan. \n\nHuomioi, että julkiset kanavat ovat julkisia ja näkyvät kaikille.",
|
||||||
|
"You_are_converting_the_team": "Muunnat tätä tiimiä kanavaksi",
|
||||||
|
"Display": "Näytä",
|
||||||
|
"Avatars": "Avatarit",
|
||||||
|
"Sort_by": "Lajitteluperuste",
|
||||||
|
"Group_by": "Ryhmittelyperuste",
|
||||||
|
"Types": "Tyypit",
|
||||||
|
"Expanded": "Laajennettu",
|
||||||
|
"Condensed": "Tiivistetty",
|
||||||
|
"creating_discussion": "luo keskustelua",
|
||||||
|
"Canned_Responses": "Valmiit vastaukset",
|
||||||
|
"No_match_found": "Vastineita ei löydy.",
|
||||||
|
"No_discussions": "Ei keskusteluja",
|
||||||
|
"Check_canned_responses": "Valmiiden vastausten tarkistus.",
|
||||||
|
"Searching": "Haetaan",
|
||||||
|
"Use": "Käytä",
|
||||||
|
"Shortcut": "Pikavalinta",
|
||||||
|
"Content": "Sisältö",
|
||||||
|
"Sharing": "Jaetaan",
|
||||||
|
"No_canned_responses": "Ei valmiita vastauksia",
|
||||||
|
"Send_email_confirmation": "Lähetä vahvistussähköposti",
|
||||||
|
"sending_email_confirmation": "lähettää sähköpostivahvistusta",
|
||||||
|
"Enable_Message_Parser": "Ota käyttöön viestin jäsentäjä",
|
||||||
|
"Unsupported_format": "Muotoa ei tueta",
|
||||||
|
"Downloaded_file": "Ladattu tiedosto",
|
||||||
|
"Error_Download_file": "Virhe ladattaessa tiedostoa",
|
||||||
|
"added__roomName__to_this_team": "lisäsi huoneen #{{roomName}} tähän tiimiin",
|
||||||
|
"Added__username__to_this_team": "lisäsi käyttäjän @{{user_added}} tähän tiimiin",
|
||||||
|
"Converting_team_to_channel": "Muunnetaan tiimiä kanavaksi",
|
||||||
|
"Converted__roomName__to_a_team": "muunsi huoneen #{{roomName}} tiimiksi",
|
||||||
|
"Converted__roomName__to_a_channel": "muunsi huoneen #{{roomName}} kanavaksi",
|
||||||
|
"Deleted__roomName__": "poisti huoneen #{{roomName}}",
|
||||||
|
"Message_HideType_added_user_to_team": "Piilota Käyttäjä lisätty tiimiin -ilmoitukset",
|
||||||
|
"Message_HideType_removed_user_from_team": "Piilota Käyttäjä poistettu tiimistä -ilmoitukset",
|
||||||
|
"Message_HideType_ujt": "Piilota Käyttäjä liittyi tiimiin -ilmoitukset",
|
||||||
|
"Message_HideType_ult": "Piilota Käyttäjä poistui tiimistä -ilmoitukset",
|
||||||
|
"Message_HideType_user_added_room_to_team": "Piilota Käyttäjä lisäsi huoneen tiimille -ilmoitukset",
|
||||||
|
"Message_HideType_user_converted_to_channel": "Piilota Käyttäjä muunsi tiimin kanavaksi -ilmoitukset",
|
||||||
|
"Message_HideType_user_converted_to_team": "Piilota Käyttäjä muunsi kanavan tiimiksi -ilmoitukset",
|
||||||
|
"Message_HideType_user_deleted_room_from_team": "Piilota Käyttäjä poisti huoneen tiimiltä -ilmoitukset",
|
||||||
|
"Message_HideType_user_removed_room_from_team": "Piilota Käyttäjä poisti huoneen tiimiltä -ilmoitukset",
|
||||||
|
"Removed__roomName__from_the_team": "poisti huoneen #{{roomName}} tästä tiimistä",
|
||||||
|
"Removed__username__from_the_team": "poisti käyttäjän @{{userRemoved}} tästä tiimistä",
|
||||||
|
"User_joined_team": "liittyi tähän tiimiin",
|
||||||
|
"User_left_team": "poistui tästä tiimistä",
|
||||||
|
"Place_chat_on_hold": "Aseta keskustelu pitoon",
|
||||||
|
"Would_like_to_place_on_hold": "Haluatko asettaa tämän keskustelun pitoon?",
|
||||||
|
"Open_Livechats": "Meneillään olevat Omnichannel-keskustelut",
|
||||||
|
"On_hold_Livechats": "Pidossa olevat Omnichannel-keskustelut",
|
||||||
|
"Chat_is_on_hold": "Tämä keskustelu on pidossa käyttämättömyyden vuoksi",
|
||||||
|
"Resume": "Jatka",
|
||||||
|
"Omnichannel_placed_chat_on_hold": "Keskustelu pidossa: {{comment}}",
|
||||||
|
"Omnichannel_on_hold_chat_resumed": "Pidossa olevaa keskustelua jatkettiin: {{comment}}",
|
||||||
|
"Omnichannel_queue": "Omnichannel-jono",
|
||||||
|
"Empty": "Tyhjä",
|
||||||
|
"Mark_as_unread": "Merkitse lukemattomaksi",
|
||||||
|
"Mark_as_unread_Info": "Näytä huone lukemattomana, kun siinä on lukemattomia viestejä",
|
||||||
|
"Show_badge_for_mentions": "Näytä mainintojen merkki",
|
||||||
|
"Show_badge_for_mentions_Info": "Näytä vain suorien mainintojen merkki",
|
||||||
|
"error-init-video-conf": "Virhe aloitettaessa videopuhelua",
|
||||||
|
"totp-invalid": "Koodi tai salasana virheellinen",
|
||||||
|
"Close_Chat": "Sulje keskustelu",
|
||||||
|
"Select_tags": "Valitse tunnisteet",
|
||||||
|
"Skip": "Ohita",
|
||||||
|
"N_Selected_members": "{{n}} valittu",
|
||||||
|
"Broadcast": "Lähetys",
|
||||||
|
"Broadcast_hint": "Vain valtuutetut käyttäjät voivat kirjoittaa uusia viestejä, mutta muut käyttäjät voivat vastata",
|
||||||
|
"Team_hint_private": "Vain kutsutut henkilöt voivat liittyä",
|
||||||
|
"Team_hint_public": "Kun tämä ei ole käytössä, kuka tahansa voi liittyä tiimiin",
|
||||||
|
"Team_hint_not_read_only": "Kaikki tämän tiimin käyttäjät voivat kirjoittaa viestejä",
|
||||||
|
"Team_hint_encrypted": "Täysin salattu tiimi. Haku ei toimi salatuissa tiimeissä eikä viestien sisältö välttämättä näy ilmoituksissa.",
|
||||||
|
"Team_hint_encrypted_not_available": "Käytettävissä vain yksityisessä tiimissä",
|
||||||
|
"Channel_hint_private": "Vain kutsutuilla käyttäjillä on pääsy tälle kanavalle",
|
||||||
|
"Channel_hint_public": "Kaikilla on pääsy tälle kanavalle",
|
||||||
|
"Channel_hint_encrypted": "Täysin salattu kanava. Haku ei toimi salatuilla kanavilla eikä viestien sisältö välttämättä näy ilmoituksissa.",
|
||||||
|
"Channel_hint_not_read_only": "Kaikki kanavan käyttäjät voivat kirjoittaa uusia viestejä",
|
||||||
|
"Channel_hint_encrypted_not_available": "Ei käytettävissä julkisilla kanavilla",
|
||||||
|
"Read_only_hint": "Vain valtuutetut käyttäjät voivat kirjoittaa uusia viestejä",
|
||||||
|
"Discussion": "Keskustelu",
|
||||||
|
"Channel": "Kanava",
|
||||||
|
"Team": "Tiimi",
|
||||||
|
"Select_Members": "Valitse jäsenet",
|
||||||
|
"Also_send_thread_message_to_channel_behavior": "Lähetä ketjun viesti myös kanavalle",
|
||||||
|
"Accounts_Default_User_Preferences_alsoSendThreadToChannel_Description": "Salli käyttäjien valita Lähetä myös kanavalle -toiminta",
|
||||||
|
"Waiting_for_answer": "Odotetaan vastausta",
|
||||||
|
"Call_ended": "Puhelu päättyi",
|
||||||
|
"Call_was_not_answered": "Puheluun ei vastattu",
|
||||||
|
"Call_back": "Soita takaisin",
|
||||||
|
"Call_again": "Soita uudelleen",
|
||||||
|
"Call_ongoing": "Puhelu käynnissä",
|
||||||
|
"Joined": "Liitytty",
|
||||||
|
"Calling": "Soitetaan...",
|
||||||
|
"Start_a_call": "Aloita puhelu",
|
||||||
|
"Call": "Soita",
|
||||||
|
"Reply_in_direct_message": "Vastaa suoralla viestillä",
|
||||||
|
"room_archived": "arkistoi huoneen",
|
||||||
|
"room_unarchived": "palautti huoneen arkistosta"
|
||||||
|
}
|
|
@ -313,6 +313,7 @@
|
||||||
"Message_accessibility": "Message de {{user}} à {{time}} : {{message}}",
|
"Message_accessibility": "Message de {{user}} à {{time}} : {{message}}",
|
||||||
"Message_actions": "Actions de message",
|
"Message_actions": "Actions de message",
|
||||||
"Message_pinned": "Message épinglé",
|
"Message_pinned": "Message épinglé",
|
||||||
|
"Message_removed": "Message supprimé",
|
||||||
"Message_starred": "Message suivi",
|
"Message_starred": "Message suivi",
|
||||||
"Message_unstarred": "Message non suivi",
|
"Message_unstarred": "Message non suivi",
|
||||||
"message": "message",
|
"message": "message",
|
||||||
|
@ -779,6 +780,7 @@
|
||||||
"Message_HideType_user_deleted_room_from_team": "Masquer les messages \"L'utilisateur a supprimé le salon de l'équipe\"",
|
"Message_HideType_user_deleted_room_from_team": "Masquer les messages \"L'utilisateur a supprimé le salon de l'équipe\"",
|
||||||
"Message_HideType_user_removed_room_from_team": "Masquer les messages \"L'utilisateur a enlevé le salon de l'équipe\"",
|
"Message_HideType_user_removed_room_from_team": "Masquer les messages \"L'utilisateur a enlevé le salon de l'équipe\"",
|
||||||
"User_joined_team": "a rejoint cette équipe",
|
"User_joined_team": "a rejoint cette équipe",
|
||||||
|
"User_left_team": "a quitté cette équipe",
|
||||||
"Place_chat_on_hold": "Mettre le chat en attente",
|
"Place_chat_on_hold": "Mettre le chat en attente",
|
||||||
"Would_like_to_place_on_hold": "Souhaitez-vous mettre ce chat en attente ?",
|
"Would_like_to_place_on_hold": "Souhaitez-vous mettre ce chat en attente ?",
|
||||||
"Open_Livechats": "Chats omnicanaux en cours",
|
"Open_Livechats": "Chats omnicanaux en cours",
|
||||||
|
|
|
@ -191,6 +191,7 @@
|
||||||
"DELETE": "ELIMINA",
|
"DELETE": "ELIMINA",
|
||||||
"Delete_Account": "Elimina account",
|
"Delete_Account": "Elimina account",
|
||||||
"Delete_Account_confirm": "Sì, Elimina",
|
"Delete_Account_confirm": "Sì, Elimina",
|
||||||
|
"move": "spostare",
|
||||||
"deleting_room": "cancellazione stanza",
|
"deleting_room": "cancellazione stanza",
|
||||||
"description": "descrizione",
|
"description": "descrizione",
|
||||||
"Description": "Descrizione",
|
"Description": "Descrizione",
|
||||||
|
@ -320,6 +321,7 @@
|
||||||
"Message_accessibility": "Messaggio da {{user}} alle {{time}}: {{message}}",
|
"Message_accessibility": "Messaggio da {{user}} alle {{time}}: {{message}}",
|
||||||
"Message_actions": "Azioni messaggio",
|
"Message_actions": "Azioni messaggio",
|
||||||
"Message_pinned": "Messaggio appuntato",
|
"Message_pinned": "Messaggio appuntato",
|
||||||
|
"Message_removed": "Messaggio rimosso",
|
||||||
"Message_starred": "Messaggio importante",
|
"Message_starred": "Messaggio importante",
|
||||||
"Message_unstarred": "Messaggio non importante",
|
"Message_unstarred": "Messaggio non importante",
|
||||||
"message": "messaggio",
|
"message": "messaggio",
|
||||||
|
@ -687,5 +689,6 @@
|
||||||
"Enter_workspace_URL": "Inserisci la url del workspace",
|
"Enter_workspace_URL": "Inserisci la url del workspace",
|
||||||
"Workspace_URL_Example": "Es. tua-azienda.rocket.chat",
|
"Workspace_URL_Example": "Es. tua-azienda.rocket.chat",
|
||||||
"invalid-room": "Canale non valido",
|
"invalid-room": "Canale non valido",
|
||||||
|
"Open_Livechats": "Chat in corso",
|
||||||
"Broadcast_hint": "Solo gli utenti autorizzati possono scrivere messaggi, ma gli altri utenti saranno in grado di rispondere"
|
"Broadcast_hint": "Solo gli utenti autorizzati possono scrivere messaggi, ma gli altri utenti saranno in grado di rispondere"
|
||||||
}
|
}
|
|
@ -313,6 +313,7 @@
|
||||||
"Message_accessibility": "Bericht van {{user}} om {{time}}: {{message}}",
|
"Message_accessibility": "Bericht van {{user}} om {{time}}: {{message}}",
|
||||||
"Message_actions": "Berichtacties",
|
"Message_actions": "Berichtacties",
|
||||||
"Message_pinned": "Bericht vastgezet",
|
"Message_pinned": "Bericht vastgezet",
|
||||||
|
"Message_removed": "Bericht verwijderd",
|
||||||
"Message_starred": "Bericht met ster",
|
"Message_starred": "Bericht met ster",
|
||||||
"Message_unstarred": "Bericht zonder ster",
|
"Message_unstarred": "Bericht zonder ster",
|
||||||
"message": "bericht",
|
"message": "bericht",
|
||||||
|
@ -779,6 +780,7 @@
|
||||||
"Message_HideType_user_deleted_room_from_team": "Verberg \"Gebruiker heeft kamer uit team verwijderd\" berichten",
|
"Message_HideType_user_deleted_room_from_team": "Verberg \"Gebruiker heeft kamer uit team verwijderd\" berichten",
|
||||||
"Message_HideType_user_removed_room_from_team": "Verberg \"Gebruiker heeft kamer uit team verwijderd\" berichten",
|
"Message_HideType_user_removed_room_from_team": "Verberg \"Gebruiker heeft kamer uit team verwijderd\" berichten",
|
||||||
"User_joined_team": "is lid geworden van dit team",
|
"User_joined_team": "is lid geworden van dit team",
|
||||||
|
"User_left_team": "heeft dit team verlaten",
|
||||||
"Place_chat_on_hold": "Chat in de wacht zetten",
|
"Place_chat_on_hold": "Chat in de wacht zetten",
|
||||||
"Would_like_to_place_on_hold": "Wil je deze chat in de wacht zetten?",
|
"Would_like_to_place_on_hold": "Wil je deze chat in de wacht zetten?",
|
||||||
"Open_Livechats": "Omnichannels-chats bezig",
|
"Open_Livechats": "Omnichannels-chats bezig",
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
"error-could-not-change-email": "Não foi possível mudar e-mail",
|
"error-could-not-change-email": "Não foi possível mudar e-mail",
|
||||||
"error-could-not-change-name": "Não foi possível mudar o nome",
|
"error-could-not-change-name": "Não foi possível mudar o nome",
|
||||||
"error-could-not-change-username": "Não foi possível alterar o nome de usuário",
|
"error-could-not-change-username": "Não foi possível alterar o nome de usuário",
|
||||||
|
"error-could-not-change-status": "Não foi possível alterar o status",
|
||||||
"error-delete-protected-role": "Não é possível remover um papel protegido",
|
"error-delete-protected-role": "Não é possível remover um papel protegido",
|
||||||
"error-department-not-found": "Departamento não encontrado",
|
"error-department-not-found": "Departamento não encontrado",
|
||||||
"error-direct-message-file-upload-not-allowed": "Compartilhamento de arquivos não está permitido em mensagens diretas",
|
"error-direct-message-file-upload-not-allowed": "Compartilhamento de arquivos não está permitido em mensagens diretas",
|
||||||
|
@ -19,6 +20,7 @@
|
||||||
"error-email-domain-blacklisted": "O domínio de e-mail está na lista negra",
|
"error-email-domain-blacklisted": "O domínio de e-mail está na lista negra",
|
||||||
"error-email-send-failed": "Erro ao tentar enviar e-mail: {{message}}",
|
"error-email-send-failed": "Erro ao tentar enviar e-mail: {{message}}",
|
||||||
"error-save-image": "Erro ao salvar imagem",
|
"error-save-image": "Erro ao salvar imagem",
|
||||||
|
"error-save-video": "Erro ao salvar vídeo",
|
||||||
"error-field-unavailable": "{{field}} já está sendo usado :(",
|
"error-field-unavailable": "{{field}} já está sendo usado :(",
|
||||||
"error-file-too-large": "Arquivo é muito grande",
|
"error-file-too-large": "Arquivo é muito grande",
|
||||||
"error-not-permission-to-upload-file": "Você não tem permissão para enviar arquivos",
|
"error-not-permission-to-upload-file": "Você não tem permissão para enviar arquivos",
|
||||||
|
@ -88,6 +90,7 @@
|
||||||
"Add_Reaction": "Reagir",
|
"Add_Reaction": "Reagir",
|
||||||
"Add_Server": "Adicionar servidor",
|
"Add_Server": "Adicionar servidor",
|
||||||
"Add_users": "Adicionar usuário",
|
"Add_users": "Adicionar usuário",
|
||||||
|
"Admin_Panel": "Painel de admin",
|
||||||
"Agent": "Agente",
|
"Agent": "Agente",
|
||||||
"Alert": "Alerta",
|
"Alert": "Alerta",
|
||||||
"alert": "alerta",
|
"alert": "alerta",
|
||||||
|
@ -96,6 +99,7 @@
|
||||||
"All_users_in_the_team_can_write_new_messages": "Todos usuários no canal podem enviar mensagens novas",
|
"All_users_in_the_team_can_write_new_messages": "Todos usuários no canal podem enviar mensagens novas",
|
||||||
"A_meaningful_name_for_the_discussion_room": "Um nome significativo para o canal de discussão",
|
"A_meaningful_name_for_the_discussion_room": "Um nome significativo para o canal de discussão",
|
||||||
"All": "Todos",
|
"All": "Todos",
|
||||||
|
"All_Messages": "Todas as mensagens",
|
||||||
"Allow_Reactions": "Permitir reagir",
|
"Allow_Reactions": "Permitir reagir",
|
||||||
"Alphabetical": "Alfabético",
|
"Alphabetical": "Alfabético",
|
||||||
"and_more": "e mais",
|
"and_more": "e mais",
|
||||||
|
@ -163,7 +167,10 @@
|
||||||
"Copied_to_clipboard": "Copiado para a área de transferência!",
|
"Copied_to_clipboard": "Copiado para a área de transferência!",
|
||||||
"Copy": "Copiar",
|
"Copy": "Copiar",
|
||||||
"Conversation": "Conversação",
|
"Conversation": "Conversação",
|
||||||
|
"Certificate_password": "Senha do certificado",
|
||||||
|
"Clear_cache": "Limpar cache da workspace",
|
||||||
"Clear_cache_loading": "Limpando cache.",
|
"Clear_cache_loading": "Limpando cache.",
|
||||||
|
"Whats_the_password_for_your_certificate": "Qual é a senha para o seu certificado?",
|
||||||
"Create_account": "Criar conta",
|
"Create_account": "Criar conta",
|
||||||
"Create_Channel": "Criar Canal",
|
"Create_Channel": "Criar Canal",
|
||||||
"Create_Direct_Messages": "Criar Mensagens Diretas",
|
"Create_Direct_Messages": "Criar Mensagens Diretas",
|
||||||
|
@ -171,6 +178,7 @@
|
||||||
"Created_snippet": "criou um snippet",
|
"Created_snippet": "criou um snippet",
|
||||||
"Create_a_new_workspace": "Criar nova área de trabalho",
|
"Create_a_new_workspace": "Criar nova área de trabalho",
|
||||||
"Create": "Criar",
|
"Create": "Criar",
|
||||||
|
"Custom_Status": "Status personalizado",
|
||||||
"Dark": "Escuro",
|
"Dark": "Escuro",
|
||||||
"Dark_level": "Nível escuro",
|
"Dark_level": "Nível escuro",
|
||||||
"Default": "Padrão",
|
"Default": "Padrão",
|
||||||
|
@ -248,9 +256,14 @@
|
||||||
"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",
|
||||||
"Get_link": "Obter link",
|
"Get_link": "Obter link",
|
||||||
|
"User_joined_the_channel": "entrou no canal",
|
||||||
|
"User_joined_the_conversation": "entrou na conversa",
|
||||||
|
"User_joined_the_team": "entrou na equipe",
|
||||||
|
"User_left_this_channel": "saiu da conversa",
|
||||||
"Has_left_the_team": "saiu da equipe",
|
"Has_left_the_team": "saiu da equipe",
|
||||||
"Hide_System_Messages": "Esconder mensagens do sistema",
|
"Hide_System_Messages": "Esconder mensagens do sistema",
|
||||||
"Hide_type_messages": "Esconder mensagens de \"{{type}}\"",
|
"Hide_type_messages": "Esconder mensagens de \"{{type}}\"",
|
||||||
|
"How_It_Works": "Como funciona",
|
||||||
"Message_HideType_uj": "Utilizador Entrou",
|
"Message_HideType_uj": "Utilizador Entrou",
|
||||||
"Message_HideType_ul": "Utilizador Saiu",
|
"Message_HideType_ul": "Utilizador Saiu",
|
||||||
"Message_HideType_ru": "Utilizador Removido",
|
"Message_HideType_ru": "Utilizador Removido",
|
||||||
|
@ -264,11 +277,15 @@
|
||||||
"Message_HideType_subscription_role_removed": "Papel removido",
|
"Message_HideType_subscription_role_removed": "Papel removido",
|
||||||
"Message_HideType_room_archived": "Sala arquivada",
|
"Message_HideType_room_archived": "Sala arquivada",
|
||||||
"Message_HideType_room_unarchived": "Sala desarquivada",
|
"Message_HideType_room_unarchived": "Sala desarquivada",
|
||||||
|
"I_Saved_My_E2E_Password": "Salvei minha senha ponta-a-ponta",
|
||||||
"IP": "IP",
|
"IP": "IP",
|
||||||
"In_app": "No app",
|
"In_app": "No app",
|
||||||
|
"In_App_And_Desktop": "In-app e área de trabalho",
|
||||||
"In_App_and_Desktop_Alert_info": "Exibe um banner na parte superior da tela quando o aplicativo é aberto e exibe uma notificação na área de trabalho",
|
"In_App_and_Desktop_Alert_info": "Exibe um banner na parte superior da tela quando o aplicativo é aberto e exibe uma notificação na área de trabalho",
|
||||||
"Invisible": "Invisível",
|
"Invisible": "Invisível",
|
||||||
"Invite": "Convidar",
|
"Invite": "Convidar",
|
||||||
|
"is_a_valid_RocketChat_instance": "é uma instância Rocket.Chat",
|
||||||
|
"is_not_a_valid_RocketChat_instance": "não é uma instância Rocket.Chat",
|
||||||
"is_typing": "está digitando",
|
"is_typing": "está digitando",
|
||||||
"Invalid_or_expired_invite_token": "Token de convite inválido ou vencido",
|
"Invalid_or_expired_invite_token": "Token de convite inválido ou vencido",
|
||||||
"Invalid_server_version": "O servidor que você está conectando não é suportado mais por esta versão do aplicativo: {{currentVersion}}.\n\nEsta versão do aplicativo requer a versão {{minVersion}} do servidor para funcionar corretamente.",
|
"Invalid_server_version": "O servidor que você está conectando não é suportado mais por esta versão do aplicativo: {{currentVersion}}.\n\nEsta versão do aplicativo requer a versão {{minVersion}} do servidor para funcionar corretamente.",
|
||||||
|
@ -289,7 +306,9 @@
|
||||||
"leave": "sair",
|
"leave": "sair",
|
||||||
"Legal": "Legal",
|
"Legal": "Legal",
|
||||||
"Light": "Claro",
|
"Light": "Claro",
|
||||||
|
"License": "Licença",
|
||||||
"Livechat": "Livechat",
|
"Livechat": "Livechat",
|
||||||
|
"Livechat_edit": "Editar livechat",
|
||||||
"Livechat_transfer_return_to_the_queue": "retornou conversa para a fila",
|
"Livechat_transfer_return_to_the_queue": "retornou conversa para a fila",
|
||||||
"Login": "Entrar",
|
"Login": "Entrar",
|
||||||
"Login_error": "Suas credenciais foram rejeitadas. Tente novamente por favor!",
|
"Login_error": "Suas credenciais foram rejeitadas. Tente novamente por favor!",
|
||||||
|
@ -298,6 +317,7 @@
|
||||||
"Logout": "Sair",
|
"Logout": "Sair",
|
||||||
"Max_number_of_uses": "Número máximo de usos",
|
"Max_number_of_uses": "Número máximo de usos",
|
||||||
"Max_number_of_users_allowed_is_number": "Número máximo de usuários é {{maxUsers}}",
|
"Max_number_of_users_allowed_is_number": "Número máximo de usuários é {{maxUsers}}",
|
||||||
|
"members": "membros",
|
||||||
"Members": "Membros",
|
"Members": "Membros",
|
||||||
"Mentioned_Messages": "Mensagens mencionadas",
|
"Mentioned_Messages": "Mensagens mencionadas",
|
||||||
"mentioned": "mencionado",
|
"mentioned": "mencionado",
|
||||||
|
@ -305,14 +325,19 @@
|
||||||
"Message_accessibility": "Mensagem de {{user}} às {{time}}: {{message}}",
|
"Message_accessibility": "Mensagem de {{user}} às {{time}}: {{message}}",
|
||||||
"Message_actions": "Ações",
|
"Message_actions": "Ações",
|
||||||
"Message_pinned": "Fixou uma mensagem",
|
"Message_pinned": "Fixou uma mensagem",
|
||||||
|
"Message_removed": "mensagem removida",
|
||||||
|
"Message_starred": "Mensagem adicionada aos favoritos",
|
||||||
|
"Message_unstarred": "Mensagem removida dos favoritos",
|
||||||
"message": "mensagem",
|
"message": "mensagem",
|
||||||
"messages": "mensagens",
|
"messages": "mensagens",
|
||||||
"Message": "Mensagem",
|
"Message": "Mensagem",
|
||||||
"Messages": "Mensagens",
|
"Messages": "Mensagens",
|
||||||
|
"Message_Reported": "Mensagem reportada",
|
||||||
"Microphone_Permission_Message": "Rocket.Chat precisa de acesso ao seu microfone para enviar mensagens de áudio.",
|
"Microphone_Permission_Message": "Rocket.Chat precisa de acesso ao seu microfone para enviar mensagens de áudio.",
|
||||||
"Microphone_Permission": "Acesso ao Microfone",
|
"Microphone_Permission": "Acesso ao Microfone",
|
||||||
"Mute": "Mudo",
|
"Mute": "Mudo",
|
||||||
"muted": "mudo",
|
"muted": "mudo",
|
||||||
|
"My_servers": "Minhas workspaces",
|
||||||
"N_people_reacted": "{{n}} pessoas reagiram",
|
"N_people_reacted": "{{n}} pessoas reagiram",
|
||||||
"N_users": "{{n}} usuários",
|
"N_users": "{{n}} usuários",
|
||||||
"N_channels": "{{n}} canais",
|
"N_channels": "{{n}} canais",
|
||||||
|
@ -321,18 +346,22 @@
|
||||||
"New_chat_transfer": "Nova transferência de conversa: {{agent}} retornou conversa para a fila",
|
"New_chat_transfer": "Nova transferência de conversa: {{agent}} retornou conversa para a fila",
|
||||||
"New_Message": "Nova Mensagem",
|
"New_Message": "Nova Mensagem",
|
||||||
"New_Password": "Nova Senha",
|
"New_Password": "Nova Senha",
|
||||||
|
"New_Server": "Nova workspace",
|
||||||
"Next": "Próximo",
|
"Next": "Próximo",
|
||||||
"No_files": "Não há arquivos",
|
"No_files": "Não há arquivos",
|
||||||
"No_limit": "Sem limite",
|
"No_limit": "Sem limite",
|
||||||
"No_mentioned_messages": "Não há menções",
|
"No_mentioned_messages": "Não há menções",
|
||||||
"No_pinned_messages": "Não há mensagens fixadas",
|
"No_pinned_messages": "Não há mensagens fixadas",
|
||||||
"No_results_found": "Nenhum resultado encontrado",
|
"No_results_found": "Nenhum resultado encontrado",
|
||||||
|
"No_members_found": "Nenhum usuário encontrado",
|
||||||
"No_starred_messages": "Não há mensagens favoritas",
|
"No_starred_messages": "Não há mensagens favoritas",
|
||||||
"No_thread_messages": "Não há tópicos",
|
"No_thread_messages": "Não há tópicos",
|
||||||
"No_label_provided": "Sem {{label}}.",
|
"No_label_provided": "Sem {{label}}.",
|
||||||
"No_Message": "Não há mensagens",
|
"No_Message": "Não há mensagens",
|
||||||
"No_messages_yet": "Não há mensagens ainda",
|
"No_messages_yet": "Não há mensagens ainda",
|
||||||
"No_Reactions": "Sem reações",
|
"No_Reactions": "Sem reações",
|
||||||
|
"No_Read_Receipts": "Não lida",
|
||||||
|
"Not_logged": "Desconectado",
|
||||||
"Not_RC_Server": "Este não é um servidor Rocket.Chat.\n{{contact}}",
|
"Not_RC_Server": "Este não é um servidor Rocket.Chat.\n{{contact}}",
|
||||||
"Nothing": "Nada",
|
"Nothing": "Nada",
|
||||||
"Nothing_to_save": "Nada para salvar!",
|
"Nothing_to_save": "Nada para salvar!",
|
||||||
|
@ -420,11 +449,21 @@
|
||||||
"Roles": "Papéis",
|
"Roles": "Papéis",
|
||||||
"Room_actions": "Ações",
|
"Room_actions": "Ações",
|
||||||
"Room_changed_announcement": "O anúncio da sala foi alterado para: {{announcement}} por {{userBy}}",
|
"Room_changed_announcement": "O anúncio da sala foi alterado para: {{announcement}} por {{userBy}}",
|
||||||
|
"room_avatar_changed": "alterou avatar da sala",
|
||||||
"Room_changed_description": "A descrição da sala foi alterada para: {{description}} por {{userBy}}",
|
"Room_changed_description": "A descrição da sala foi alterada para: {{description}} por {{userBy}}",
|
||||||
|
"changed_room_description": "alterou a descrição da sala para: {{description}}",
|
||||||
|
"changed_room_announcement": "alterou o anúncio da sala para: {{announcement}}",
|
||||||
|
"room_changed_type": "mudou sala para {{type}}",
|
||||||
|
"room_changed_topic_to": "mudou tópico da sala para: {{topic}}",
|
||||||
"Room_Files": "Arquivos",
|
"Room_Files": "Arquivos",
|
||||||
"Room_Info_Edit": "Editar",
|
"Room_Info_Edit": "Editar",
|
||||||
"Room_Info": "Informações da Sala",
|
"Room_Info": "Informações da Sala",
|
||||||
"Room_Members": "Membros",
|
"Room_Members": "Membros",
|
||||||
|
"Room_name_changed_to": "alterou o nome da sala para: {{name}}",
|
||||||
|
"room_disallowed_reactions": "removeu a permissão de reagir",
|
||||||
|
"room_allowed_reactions": "adicionou permissão de reagir",
|
||||||
|
"room_removed_read_only_permission": "removeu permissão de escrita da sala",
|
||||||
|
"room_set_read_only_permission": "adicionou permissão de escrita à sala",
|
||||||
"SAVE": "SALVAR",
|
"SAVE": "SALVAR",
|
||||||
"Save_Changes": "Salvar Alterações",
|
"Save_Changes": "Salvar Alterações",
|
||||||
"Save": "Salvar",
|
"Save": "Salvar",
|
||||||
|
@ -440,8 +479,10 @@
|
||||||
"Search_Messages": "Buscar Mensagens",
|
"Search_Messages": "Buscar Mensagens",
|
||||||
"Search": "Buscar",
|
"Search": "Buscar",
|
||||||
"Search_by": "Buscar por",
|
"Search_by": "Buscar por",
|
||||||
|
"Search_emoji": "Buscar emoji",
|
||||||
"Search_global_users": "Busca por usuários globais",
|
"Search_global_users": "Busca por usuários globais",
|
||||||
"Search_global_users_description": "Caso ativado, busca por usuários de outras empresas ou servidores.",
|
"Search_global_users_description": "Caso ativado, busca por usuários de outras empresas ou servidores.",
|
||||||
|
"Seconds": "{{second}} segundos",
|
||||||
"Security_and_privacy": "Segurança e privacidade",
|
"Security_and_privacy": "Segurança e privacidade",
|
||||||
"Select_Avatar": "Selecionar Avatar",
|
"Select_Avatar": "Selecionar Avatar",
|
||||||
"Select_Server": "Selecionar Servidor",
|
"Select_Server": "Selecionar Servidor",
|
||||||
|
@ -456,13 +497,20 @@
|
||||||
"Send_message": "Enviar mensagem",
|
"Send_message": "Enviar mensagem",
|
||||||
"Send_me_the_code_again": "Envie-me o código novamente",
|
"Send_me_the_code_again": "Envie-me o código novamente",
|
||||||
"Send_to": "Enviar para...",
|
"Send_to": "Enviar para...",
|
||||||
|
"Sending_to": "Envio para",
|
||||||
"Sent_an_attachment": "Enviou um anexo",
|
"Sent_an_attachment": "Enviou um anexo",
|
||||||
"Server": "Servidor",
|
"Server": "Servidor",
|
||||||
|
"Servers": "Workspaces",
|
||||||
|
"Server_version": "Versão da workspace: {{version}}",
|
||||||
"Set_username_subtitle": "O usuário é utilizado para permitir que você seja mencionado em mensagens",
|
"Set_username_subtitle": "O usuário é utilizado para permitir que você seja mencionado em mensagens",
|
||||||
|
"Set_custom_status": "Definir status personalizado",
|
||||||
|
"Set_status": "Definir status",
|
||||||
|
"Status_saved_successfully": "Status salvo com sucesso!",
|
||||||
"Settings": "Configurações",
|
"Settings": "Configurações",
|
||||||
"Settings_succesfully_changed": "Configurações salvas com sucesso!",
|
"Settings_succesfully_changed": "Configurações salvas com sucesso!",
|
||||||
"Share": "Compartilhar",
|
"Share": "Compartilhar",
|
||||||
"Share_Link": "Share Link",
|
"Share_Link": "Share Link",
|
||||||
|
"Share_this_app": "Compartilhar esse app",
|
||||||
"Show_more": "Mostrar mais..",
|
"Show_more": "Mostrar mais..",
|
||||||
"Sign_in_your_server": "Entrar no seu servidor",
|
"Sign_in_your_server": "Entrar no seu servidor",
|
||||||
"Sign_Up": "Registrar",
|
"Sign_Up": "Registrar",
|
||||||
|
@ -479,9 +527,12 @@
|
||||||
"Started_call": "Chamada iniciada por {{userBy}}",
|
"Started_call": "Chamada iniciada por {{userBy}}",
|
||||||
"Submit": "Enviar",
|
"Submit": "Enviar",
|
||||||
"Table": "Tabela",
|
"Table": "Tabela",
|
||||||
|
"Tags": "Tags",
|
||||||
"Take_a_photo": "Tirar uma foto",
|
"Take_a_photo": "Tirar uma foto",
|
||||||
"Take_a_video": "Gravar um vídeo",
|
"Take_a_video": "Gravar um vídeo",
|
||||||
"Take_it": "Pegue!",
|
"Take_it": "Pegue!",
|
||||||
|
"tap_to_change_status": "toque para mudar de status",
|
||||||
|
"Tap_to_view_servers_list": "Toque para visualizar as workspaces",
|
||||||
"Terms_of_Service": " Termos de Serviço ",
|
"Terms_of_Service": " Termos de Serviço ",
|
||||||
"Theme": "Tema",
|
"Theme": "Tema",
|
||||||
"The_user_wont_be_able_to_type_in_roomName": "O usuário não poderá digitar em {{roomName}}",
|
"The_user_wont_be_able_to_type_in_roomName": "O usuário não poderá digitar em {{roomName}}",
|
||||||
|
@ -513,17 +564,27 @@
|
||||||
"Unsupported_system_message": "Mensagem de sistema não suportada",
|
"Unsupported_system_message": "Mensagem de sistema não suportada",
|
||||||
"Updating": "Atualizando...",
|
"Updating": "Atualizando...",
|
||||||
"Uploading": "Subindo arquivo",
|
"Uploading": "Subindo arquivo",
|
||||||
|
"FileUpload_Error": "Erro de upload de arquivo",
|
||||||
|
"Upload_in_progress": "Carregamento em andamento",
|
||||||
"Upload_file_question_mark": "Enviar arquivo?",
|
"Upload_file_question_mark": "Enviar arquivo?",
|
||||||
"User": "Usuário",
|
"User": "Usuário",
|
||||||
"Users": "Usuários",
|
"Users": "Usuários",
|
||||||
|
"User_added_to": "adicionou o usuário {{userAdded}}",
|
||||||
"User_Info": "Informações do usuário",
|
"User_Info": "Informações do usuário",
|
||||||
"User_has_been_key": "Usuário foi {{key}}",
|
"User_has_been_key": "Usuário foi {{key}}",
|
||||||
"User_is_no_longer_role_by_": "{{user}} não pertence mais à {{role}} por {{userBy}}",
|
"User_is_no_longer_role_by_": "{{user}} não pertence mais à {{role}} por {{userBy}}",
|
||||||
|
"User_has_been_muted": "silenciou o usuário {{userMuted}}",
|
||||||
|
"User_has_been_removed": "removeu {{userRemoved}}",
|
||||||
"User_sent_an_attachment": "{{user}} enviou um anexo",
|
"User_sent_an_attachment": "{{user}} enviou um anexo",
|
||||||
|
"User_has_been_unmuted": "permitiu que {{userUnmuted}} fale na sala",
|
||||||
|
"Defined_user_as_role": "definiu {{user}} como {{role}}",
|
||||||
|
"Removed_user_as_role": "removeu {{user}} como {{role}}",
|
||||||
"Username_is_empty": "Usuário está vazio",
|
"Username_is_empty": "Usuário está vazio",
|
||||||
"Username": "Usuário",
|
"Username": "Usuário",
|
||||||
"Username_or_email": "Usuário ou email",
|
"Username_or_email": "Usuário ou email",
|
||||||
"Uses_server_configuration": "Usar configuração do servidor",
|
"Uses_server_configuration": "Usar configuração do servidor",
|
||||||
|
"Validating": "Validando...",
|
||||||
|
"Registration_Succeeded": "Registrado com sucesso!",
|
||||||
"Verify": "Verificar",
|
"Verify": "Verificar",
|
||||||
"Verify_email_title": "Registrado com sucesso!",
|
"Verify_email_title": "Registrado com sucesso!",
|
||||||
"Verify_email_desc": "Nós lhe enviamos um e-mail para confirmar o seu registro. Se você não receber um e-mail em breve, por favor retorne e tente novamente.",
|
"Verify_email_desc": "Nós lhe enviamos um e-mail para confirmar o seu registro. Se você não receber um e-mail em breve, por favor retorne e tente novamente.",
|
||||||
|
@ -552,7 +613,9 @@
|
||||||
"You_were_removed_from_channel": "Você foi removido de {{channel}}",
|
"You_were_removed_from_channel": "Você foi removido de {{channel}}",
|
||||||
"you": "você",
|
"you": "você",
|
||||||
"You": "Você",
|
"You": "Você",
|
||||||
|
"Logged_out_by_server": "Você foi desconectado pela workspace. Por favor entre novamente.",
|
||||||
"Token_expired": "Sua sessão expirou. Por favor entre novamente.",
|
"Token_expired": "Sua sessão expirou. Por favor entre novamente.",
|
||||||
|
"You_need_to_access_at_least_one_RocketChat_server_to_share_something": "Você precisa acessar pelo menos uma workspace Rocket.Chat para compartilhar.",
|
||||||
"You_need_to_verifiy_your_email_address_to_get_notications": "Você precisa confirmar seu endereço de e-mail para obter notificações",
|
"You_need_to_verifiy_your_email_address_to_get_notications": "Você precisa confirmar seu endereço de e-mail para obter notificações",
|
||||||
"Your_certificate": "Seu certificado",
|
"Your_certificate": "Seu certificado",
|
||||||
"Your_invite_link_will_expire_after__usesLeft__uses": "Seu link de convite irá vencer depois de {{usesLeft}} usos.",
|
"Your_invite_link_will_expire_after__usesLeft__uses": "Seu link de convite irá vencer depois de {{usesLeft}} usos.",
|
||||||
|
@ -560,6 +623,8 @@
|
||||||
"Your_invite_link_will_expire_on__date__": "Seu link de convite irá vencer em {{date}}.",
|
"Your_invite_link_will_expire_on__date__": "Seu link de convite irá vencer em {{date}}.",
|
||||||
"Your_invite_link_will_never_expire": "Seu link de convite nunca irá vencer.",
|
"Your_invite_link_will_never_expire": "Seu link de convite nunca irá vencer.",
|
||||||
"Your_workspace": "Sua workspace",
|
"Your_workspace": "Sua workspace",
|
||||||
|
"Your_password_is": "Sua senha é",
|
||||||
|
"Version_no": "Versão: {{version}}",
|
||||||
"You_will_not_be_able_to_recover_this_message": "Você não será capaz de recuperar essa mensagem!",
|
"You_will_not_be_able_to_recover_this_message": "Você não será capaz de recuperar essa mensagem!",
|
||||||
"You_will_unset_a_certificate_for_this_server": "Você cancelará a configuração de um certificado para este servidor",
|
"You_will_unset_a_certificate_for_this_server": "Você cancelará a configuração de um certificado para este servidor",
|
||||||
"Change_Language": "Alterar idioma",
|
"Change_Language": "Alterar idioma",
|
||||||
|
@ -655,9 +720,15 @@
|
||||||
"Message_Ignored": "Mensagem ignorada. Toque para mostrar.",
|
"Message_Ignored": "Mensagem ignorada. Toque para mostrar.",
|
||||||
"Enter_workspace_URL": "Digite a URL da sua workspace",
|
"Enter_workspace_URL": "Digite a URL da sua workspace",
|
||||||
"Workspace_URL_Example": "Ex. sua-empresa.rocket.chat",
|
"Workspace_URL_Example": "Ex. sua-empresa.rocket.chat",
|
||||||
|
"Enabled_E2E_Encryption_for_this_room": "habilitou criptografia para essa sala",
|
||||||
|
"Disabled_E2E_Encryption_for_this_room": "desabilitou criptografia para essa sala",
|
||||||
"Teams": "Times",
|
"Teams": "Times",
|
||||||
"No_team_channels_found": "Nenhum canal encontrado",
|
"No_team_channels_found": "Nenhum canal encontrado",
|
||||||
"Team_not_found": "Time não encontrado",
|
"Team_not_found": "Time não encontrado",
|
||||||
|
"Create_Team": "Criar time",
|
||||||
|
"Team_Name": "Nome do time",
|
||||||
|
"creating_team": "criando time",
|
||||||
|
"team-name-already-exists": "Um time com esse nome já existe",
|
||||||
"Add_Channel_to_Team": "Adicionar Canal ao Time",
|
"Add_Channel_to_Team": "Adicionar Canal ao Time",
|
||||||
"Left_The_Team_Successfully": "Saiu do time com sucesso",
|
"Left_The_Team_Successfully": "Saiu do time com sucesso",
|
||||||
"Create_New": "Criar",
|
"Create_New": "Criar",
|
||||||
|
@ -734,7 +805,11 @@
|
||||||
"Unsupported_format": "Formato não suportado",
|
"Unsupported_format": "Formato não suportado",
|
||||||
"Downloaded_file": "Arquivo baixado",
|
"Downloaded_file": "Arquivo baixado",
|
||||||
"Error_Download_file": "Erro ao baixar o arquivo",
|
"Error_Download_file": "Erro ao baixar o arquivo",
|
||||||
|
"added__roomName__to_this_team": "adicionou #{{roomName}} a esta equipe",
|
||||||
|
"Added__username__to_this_team": "adicionou @{{user_added}} a esta equipe",
|
||||||
"Converting_team_to_channel": "Convertendo equipe em canal",
|
"Converting_team_to_channel": "Convertendo equipe em canal",
|
||||||
|
"Converted__roomName__to_a_team": "converteu #{{roomName}} em equipe",
|
||||||
|
"Converted__roomName__to_a_channel": "converteu #{{roomName}} em canal",
|
||||||
"Deleted__roomName__": "#{{roomName}} apagada",
|
"Deleted__roomName__": "#{{roomName}} apagada",
|
||||||
"Message_HideType_added_user_to_team": "Ocultar mensagens de \"Usuário adicionado à equipe\"",
|
"Message_HideType_added_user_to_team": "Ocultar mensagens de \"Usuário adicionado à equipe\"",
|
||||||
"Message_HideType_removed_user_from_team": "Ocultar mensagens de \"Usuário removido da equipe\"",
|
"Message_HideType_removed_user_from_team": "Ocultar mensagens de \"Usuário removido da equipe\"",
|
||||||
|
@ -745,7 +820,10 @@
|
||||||
"Message_HideType_user_converted_to_team": "Ocultar mensagens de \"Usuário converteu canal em equipe\"",
|
"Message_HideType_user_converted_to_team": "Ocultar mensagens de \"Usuário converteu canal em equipe\"",
|
||||||
"Message_HideType_user_deleted_room_from_team": "Ocultar mensagens de \"Usuário apagou sala da equipe\"",
|
"Message_HideType_user_deleted_room_from_team": "Ocultar mensagens de \"Usuário apagou sala da equipe\"",
|
||||||
"Message_HideType_user_removed_room_from_team": "Ocultar mensagens de \"Usuário removeu sala da equipe\"",
|
"Message_HideType_user_removed_room_from_team": "Ocultar mensagens de \"Usuário removeu sala da equipe\"",
|
||||||
|
"Removed__roomName__from_the_team": "removeu #{{roomName}} desta equipe",
|
||||||
|
"Removed__username__from_the_team": "removeu @{{userRemoved}} desta equipe",
|
||||||
"User_joined_team": "entrou nesta equipe",
|
"User_joined_team": "entrou nesta equipe",
|
||||||
|
"User_left_team": "saiu desta equipe",
|
||||||
"Place_chat_on_hold": "Colocar conversa em espera",
|
"Place_chat_on_hold": "Colocar conversa em espera",
|
||||||
"Would_like_to_place_on_hold": "Gostaria de colocar essa conversa Em Espera?",
|
"Would_like_to_place_on_hold": "Gostaria de colocar essa conversa Em Espera?",
|
||||||
"Open_Livechats": "Bate-papos em Andamento",
|
"Open_Livechats": "Bate-papos em Andamento",
|
||||||
|
@ -760,6 +838,7 @@
|
||||||
"Mark_as_unread_Info": "Mostrar sala como não lida quando houver mensagens não lidas",
|
"Mark_as_unread_Info": "Mostrar sala como não lida quando houver mensagens não lidas",
|
||||||
"Show_badge_for_mentions": "Mostrar contador para menções",
|
"Show_badge_for_mentions": "Mostrar contador para menções",
|
||||||
"Show_badge_for_mentions_Info": "Mostrar contador somente para menções diretas",
|
"Show_badge_for_mentions_Info": "Mostrar contador somente para menções diretas",
|
||||||
|
"error-init-video-conf": "Erro ao iniciar chamada de video",
|
||||||
"totp-invalid": "Código ou senha inválida",
|
"totp-invalid": "Código ou senha inválida",
|
||||||
"Close_Chat": "Fechar Conversa",
|
"Close_Chat": "Fechar Conversa",
|
||||||
"Select_tags": "Selecionar tag(s)",
|
"Select_tags": "Selecionar tag(s)",
|
||||||
|
@ -772,18 +851,28 @@
|
||||||
"Team_hint_not_read_only": "Todos os usuários nesta equipe podem escrever mensagens",
|
"Team_hint_not_read_only": "Todos os usuários nesta equipe podem escrever mensagens",
|
||||||
"Team_hint_encrypted": "Equipe criptografada de ponta a ponta. A pesquisa não funcionará com equipes criptografadas e as notificações poderão não exibir o conteúdo das mensagens.",
|
"Team_hint_encrypted": "Equipe criptografada de ponta a ponta. A pesquisa não funcionará com equipes criptografadas e as notificações poderão não exibir o conteúdo das mensagens.",
|
||||||
"Team_hint_encrypted_not_available": "Disponível apenas para equipes privadas",
|
"Team_hint_encrypted_not_available": "Disponível apenas para equipes privadas",
|
||||||
"Channel_hint_private":"Apenas usuários convidados podem acessar este canal",
|
"Channel_hint_private": "Apenas usuários convidados podem acessar este canal",
|
||||||
"Channel_hint_public":"Todos podem acessar este canal",
|
"Channel_hint_public": "Todos podem acessar este canal",
|
||||||
"Channel_hint_encrypted": "Canal criptografado de ponta a ponta. A pesquisa não funcionará com canais criptografados e as notificações podem não mostrar o conteúdo das mensagens.",
|
"Channel_hint_encrypted": "Canal criptografado de ponta a ponta. A pesquisa não funcionará com canais criptografados e as notificações podem não mostrar o conteúdo das mensagens.",
|
||||||
"Channel_hint_not_read_only": "Todos usuários no canal podem enviar mensagens novas",
|
"Channel_hint_not_read_only": "Todos usuários no canal podem enviar mensagens novas",
|
||||||
"Channel_hint_encrypted_not_available": "Indisponível para canais públicos",
|
"Channel_hint_encrypted_not_available": "Indisponível para canais públicos",
|
||||||
"Read_only_hint":"Somente usuários autorizados podem escrever novas mensagens",
|
"Read_only_hint": "Somente usuários autorizados podem escrever novas mensagens",
|
||||||
"Discussion": "Discussão",
|
"Discussion": "Discussão",
|
||||||
"Channel": "Canal",
|
"Channel": "Canal",
|
||||||
"Team": "Time",
|
"Team": "Time",
|
||||||
"Select_Members": "Selecionar Membros",
|
"Select_Members": "Selecionar Membros",
|
||||||
"Also_send_thread_message_to_channel_behavior": "Também enviar mensagem do tópico para o canal",
|
"Also_send_thread_message_to_channel_behavior": "Também enviar mensagem do tópico para o canal",
|
||||||
"Accounts_Default_User_Preferences_alsoSendThreadToChannel_Description": "Permitir que os usuários selecionem o comportamento Também enviar para o canal",
|
"Accounts_Default_User_Preferences_alsoSendThreadToChannel_Description": "Permitir que os usuários selecionem o comportamento Também enviar para o canal",
|
||||||
|
"Waiting_for_answer": "Esperando por resposta",
|
||||||
|
"Call_ended": "Chamada finalizada",
|
||||||
|
"Call_was_not_answered": "A chamada não foi atendida",
|
||||||
|
"Call_back": "Ligue de volta",
|
||||||
|
"Call_again": "Ligue novamente",
|
||||||
|
"Call_ongoing": "Chamada em andamento",
|
||||||
|
"Joined": "Ingressou",
|
||||||
|
"Calling": "Chamando...",
|
||||||
|
"Start_a_call": "Inicie uma chamada",
|
||||||
|
"Call": "Ligar",
|
||||||
"Reply_in_direct_message": "Responder por mensagem direta",
|
"Reply_in_direct_message": "Responder por mensagem direta",
|
||||||
"room_archived": "{{username}} arquivou a sala",
|
"room_archived": "{{username}} arquivou a sala",
|
||||||
"room_unarchived": "{{username}} desarquivou a sala"
|
"room_unarchived": "{{username}} desarquivou a sala"
|
||||||
|
|
|
@ -307,6 +307,7 @@
|
||||||
"Message_accessibility": "Mensagem de {{user}} às {{time}}: {{message}}",
|
"Message_accessibility": "Mensagem de {{user}} às {{time}}: {{message}}",
|
||||||
"Message_actions": "Acções de mensagem",
|
"Message_actions": "Acções de mensagem",
|
||||||
"Message_pinned": "Mensagem afixada",
|
"Message_pinned": "Mensagem afixada",
|
||||||
|
"Message_removed": "Mensagem removida",
|
||||||
"Message_starred": "Mensagem estrelada",
|
"Message_starred": "Mensagem estrelada",
|
||||||
"Message_unstarred": "Mensagem não estrelada",
|
"Message_unstarred": "Mensagem não estrelada",
|
||||||
"message": "mensagem",
|
"message": "mensagem",
|
||||||
|
@ -492,5 +493,6 @@
|
||||||
"you": "você",
|
"you": "você",
|
||||||
"You": "Você",
|
"You": "Você",
|
||||||
"You_will_not_be_able_to_recover_this_message": "Você será incapaz de recuperar esta mensagem!",
|
"You_will_not_be_able_to_recover_this_message": "Você será incapaz de recuperar esta mensagem!",
|
||||||
|
"Open_Livechats": "Chats em andamento",
|
||||||
"Broadcast_hint": "Apenas utilizadores autorizados podem escrever novas mensagens, mas os outros utilizadores poderão responder"
|
"Broadcast_hint": "Apenas utilizadores autorizados podem escrever novas mensagens, mas os outros utilizadores poderão responder"
|
||||||
}
|
}
|
|
@ -256,6 +256,7 @@
|
||||||
"Forward_to_user": "Перенаправить пользователю",
|
"Forward_to_user": "Перенаправить пользователю",
|
||||||
"Full_table": "Нажмите, чтобы увидеть полную таблицу",
|
"Full_table": "Нажмите, чтобы увидеть полную таблицу",
|
||||||
"Generate_New_Link": "Сгенерировать Новую Ссылку",
|
"Generate_New_Link": "Сгенерировать Новую Ссылку",
|
||||||
|
"Get_link": "Получить ссылку",
|
||||||
"Has_left_the_team": "покинул Команду",
|
"Has_left_the_team": "покинул Команду",
|
||||||
"Hide_System_Messages": "Скрыть Системные Сообщения",
|
"Hide_System_Messages": "Скрыть Системные Сообщения",
|
||||||
"Hide_type_messages": "Скрыть \"{{type}}\" сообщения",
|
"Hide_type_messages": "Скрыть \"{{type}}\" сообщения",
|
||||||
|
@ -321,6 +322,7 @@
|
||||||
"Message_accessibility": "Сообщение от {{user}} в {{time}}: {{message}}",
|
"Message_accessibility": "Сообщение от {{user}} в {{time}}: {{message}}",
|
||||||
"Message_actions": "Действия с сообщением",
|
"Message_actions": "Действия с сообщением",
|
||||||
"Message_pinned": "Сообщение прикреплено",
|
"Message_pinned": "Сообщение прикреплено",
|
||||||
|
"Message_removed": "Сообщение удалено",
|
||||||
"Message_starred": "Сообщение отмечено звездой",
|
"Message_starred": "Сообщение отмечено звездой",
|
||||||
"Message_unstarred": "Отметка сообщения звездой удалена",
|
"Message_unstarred": "Отметка сообщения звездой удалена",
|
||||||
"message": "сообщение",
|
"message": "сообщение",
|
||||||
|
@ -348,6 +350,7 @@
|
||||||
"No_mentioned_messages": "Нет упоминаний",
|
"No_mentioned_messages": "Нет упоминаний",
|
||||||
"No_pinned_messages": "Нет прикрепленных сообщений",
|
"No_pinned_messages": "Нет прикрепленных сообщений",
|
||||||
"No_results_found": "Ничего не найдено",
|
"No_results_found": "Ничего не найдено",
|
||||||
|
"No_members_found": "Участники не найдены",
|
||||||
"No_starred_messages": "Нет отмеченных сообщений",
|
"No_starred_messages": "Нет отмеченных сообщений",
|
||||||
"No_thread_messages": "Нет сообщений в теме",
|
"No_thread_messages": "Нет сообщений в теме",
|
||||||
"No_label_provided": "{{label}} не указан.",
|
"No_label_provided": "{{label}} не указан.",
|
||||||
|
@ -463,6 +466,7 @@
|
||||||
"Search_Messages": "Поиск сообщений",
|
"Search_Messages": "Поиск сообщений",
|
||||||
"Search": "Поиск",
|
"Search": "Поиск",
|
||||||
"Search_by": "Поиск по",
|
"Search_by": "Поиск по",
|
||||||
|
"Search_emoji": "Поиск эмодзи",
|
||||||
"Search_global_users": "Глобальный поиск пользователей",
|
"Search_global_users": "Глобальный поиск пользователей",
|
||||||
"Search_global_users_description": "При активации станет возможен поиск пользователей на других серверах.",
|
"Search_global_users_description": "При активации станет возможен поиск пользователей на других серверах.",
|
||||||
"Seconds": "{{second}} секунд",
|
"Seconds": "{{second}} секунд",
|
||||||
|
@ -790,6 +794,7 @@
|
||||||
"Message_HideType_user_deleted_room_from_team": "Скрыть сообщения \"Пользователь удалил чат из Команды\"",
|
"Message_HideType_user_deleted_room_from_team": "Скрыть сообщения \"Пользователь удалил чат из Команды\"",
|
||||||
"Message_HideType_user_removed_room_from_team": "Скрыть сообщения \"Пользователь удалил чат из Команды\"",
|
"Message_HideType_user_removed_room_from_team": "Скрыть сообщения \"Пользователь удалил чат из Команды\"",
|
||||||
"User_joined_team": "присоединился к Команде",
|
"User_joined_team": "присоединился к Команде",
|
||||||
|
"User_left_team": "покинул Команду",
|
||||||
"Place_chat_on_hold": "Поставить чат на удержание",
|
"Place_chat_on_hold": "Поставить чат на удержание",
|
||||||
"Would_like_to_place_on_hold": "Вы хотите поставить этот чат на удержание?",
|
"Would_like_to_place_on_hold": "Вы хотите поставить этот чат на удержание?",
|
||||||
"Open_Livechats": "Omnichannel чаты в работе",
|
"Open_Livechats": "Omnichannel чаты в работе",
|
||||||
|
@ -808,5 +813,36 @@
|
||||||
"totp-invalid": "Код или пароль не верны",
|
"totp-invalid": "Код или пароль не верны",
|
||||||
"Close_Chat": "Закрыть чат",
|
"Close_Chat": "Закрыть чат",
|
||||||
"Select_tags": "Выберите теги",
|
"Select_tags": "Выберите теги",
|
||||||
"Broadcast_hint": "Только авторизованные пользователи могут писать новые сообщения, но другие пользователи смогут ответить"
|
"Skip": "Пропустить",
|
||||||
|
"N_Selected_members": "{{n}} выбрано",
|
||||||
|
"Broadcast": "Широковещательный",
|
||||||
|
"Broadcast_hint": "Только авторизованные пользователи могут писать новые сообщения, но другие пользователи смогут ответить",
|
||||||
|
"Team_hint_private": "Только приглашенные люди могут присоединиться",
|
||||||
|
"Team_hint_public": "Когда отключено, кто угодно может присоединиться к команде",
|
||||||
|
"Team_hint_not_read_only": "Все пользователи в этой команде могут писать сообщения",
|
||||||
|
"Team_hint_encrypted": "Команда со сквозным шифрованием. Поиск не будет работать в зашифрованных командах, а уведомления могут не отображать содержание сообщений.",
|
||||||
|
"Team_hint_encrypted_not_available": "Доступно только для приватной команды",
|
||||||
|
"Channel_hint_private": "Только приглашенные пользователи могут получить доступ к этому каналу",
|
||||||
|
"Channel_hint_public": "У всех есть доступ к этому каналу",
|
||||||
|
"Channel_hint_encrypted": "Канал со сквозным шифрованием. Поиск не будет работать в зашифрованных каналах, а уведомления могут не отображать содержание сообщений.",
|
||||||
|
"Channel_hint_not_read_only": "Все пользователи канала могут писать новые сообщения",
|
||||||
|
"Channel_hint_encrypted_not_available": "Недоступно для публичных каналов",
|
||||||
|
"Read_only_hint": "Только авторизованные пользователи могут писать новые сообщения",
|
||||||
|
"Discussion": "Обсуждение",
|
||||||
|
"Channel": "Канал",
|
||||||
|
"Team": "Команда",
|
||||||
|
"Select_Members": "Выбрать участников",
|
||||||
|
"Also_send_thread_message_to_channel_behavior": "Также отправить в чат",
|
||||||
|
"Accounts_Default_User_Preferences_alsoSendThreadToChannel_Description": "Разрешить пользователям выбирать поведение \"Также отправить в чат\"",
|
||||||
|
"Waiting_for_answer": "Ожидание ответа",
|
||||||
|
"Call_ended": "Звонок завершен",
|
||||||
|
"Call_was_not_answered": "Звонок не был отвечен",
|
||||||
|
"Call_back": "Обратный звонок",
|
||||||
|
"Call_again": "Позвонить снова",
|
||||||
|
"Call_ongoing": "Идет вызов",
|
||||||
|
"Joined": "участвовал",
|
||||||
|
"Calling": "Идет вызов",
|
||||||
|
"Start_a_call": "Начать звонок",
|
||||||
|
"Call": "Звонок",
|
||||||
|
"Reply_in_direct_message": "Ответить в личном сообщении"
|
||||||
}
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1 +1,878 @@
|
||||||
{ }
|
{
|
||||||
|
"__count__empty_rooms_will_be_removed_automatically": "{{count}} tomma rum tas bort.",
|
||||||
|
"__count__empty_room_will_be_removed_automatically": "{{count}} tomt rum tas bort.",
|
||||||
|
"1_person_reacted": "1 person reagerade",
|
||||||
|
"1_user": "1 användare",
|
||||||
|
"error-action-not-allowed": "{{action}} tillåts inte",
|
||||||
|
"error-application-not-found": "Appen hittades inte",
|
||||||
|
"error-archived-duplicate-name": "Det finns en arkiverad kanal med namnet {{room_name}}",
|
||||||
|
"error-avatar-invalid-url": "Ogiltig avatar-URL: {{url}}",
|
||||||
|
"error-avatar-url-handling": "Fel vid hantering av avatarinställningar via en URL ({{url}}) för {{username}}",
|
||||||
|
"error-cant-invite-for-direct-room": "Det går inte att bjuda in användare till direkta rum",
|
||||||
|
"error-could-not-change-email": "Det gick inte att ändra e-postadressen",
|
||||||
|
"error-could-not-change-name": "Det gick inte att ändra namnet",
|
||||||
|
"error-could-not-change-username": "Det gick inte att ändra användarnamnet",
|
||||||
|
"error-could-not-change-status": "Det gick inte att ändra status",
|
||||||
|
"error-delete-protected-role": "Det går inte att radera en skyddad roll",
|
||||||
|
"error-department-not-found": "Avdelningen hittades inte",
|
||||||
|
"error-direct-message-file-upload-not-allowed": "Fildelning tillåts inte i direktmeddelanden",
|
||||||
|
"error-duplicate-channel-name": "Det finns redan en kanal med namnet {{room_name}} ",
|
||||||
|
"error-email-domain-blacklisted": "E-postdomänen är svartlistad",
|
||||||
|
"error-email-send-failed": "Fel vid försök att skicka e-postmeddelandet: {{message}}",
|
||||||
|
"error-save-image": "Fel när bilden skulle sparas",
|
||||||
|
"error-save-video": "Fel när videon skulle sparas",
|
||||||
|
"error-field-unavailable": "{{field}} används redan :(",
|
||||||
|
"error-file-too-large": "Filen är för stor",
|
||||||
|
"error-not-permission-to-upload-file": "Du har inte behörighet att ladda upp filer",
|
||||||
|
"error-importer-not-defined": "Importören har inte definierats rätt eller saknar importklass.",
|
||||||
|
"error-input-is-not-a-valid-field": "{{input}} är inte ett giltigt {{field}}",
|
||||||
|
"error-invalid-actionlink": "Ogiltig åtgärdslänk",
|
||||||
|
"error-invalid-arguments": "Ogiltiga argument",
|
||||||
|
"error-invalid-asset": "Ogiltig resurs",
|
||||||
|
"error-invalid-channel": "Ogiltig kanal.",
|
||||||
|
"error-invalid-channel-start-with-chars": "Ogiltig kanal. Börja med @ eller #",
|
||||||
|
"error-invalid-custom-field": "Ogiltigt anpassat fält",
|
||||||
|
"error-invalid-custom-field-name": "Ogiltigt anpassat fältnamn. Använd endast bokstäver, siffror, bindestreck och understreck.",
|
||||||
|
"error-invalid-date": "Ett ogiltigt datum har angetts.",
|
||||||
|
"error-invalid-description": "Ogiltig beskrivning",
|
||||||
|
"error-invalid-domain": "Ogiltig domän",
|
||||||
|
"error-invalid-email": "Ogiltig e-post {{email}}",
|
||||||
|
"error-invalid-email-address": "Ogiltig e-postadress",
|
||||||
|
"error-invalid-file-height": "Ogiltig filhöjd",
|
||||||
|
"error-invalid-file-type": "Ogiltig filtyp",
|
||||||
|
"error-invalid-file-width": "Ogiltig filbredd",
|
||||||
|
"error-invalid-from-address": "Du angav en ogiltig avsändaradress",
|
||||||
|
"error-invalid-integration": "Ogiltig integrering",
|
||||||
|
"error-invalid-message": "Ogiltigt meddelande",
|
||||||
|
"error-invalid-method": "Ogiltigt metod",
|
||||||
|
"error-invalid-name": "Ogiltigt namn",
|
||||||
|
"error-invalid-password": "Ogiltigt lösenord",
|
||||||
|
"error-invalid-redirectUri": "Ogiltig redirectUri",
|
||||||
|
"error-invalid-role": "Ogiltig roll",
|
||||||
|
"error-invalid-room": "Ogiltigt rum",
|
||||||
|
"error-invalid-room-name": "{{room_name}} är inte ett giltigt rumsnamn",
|
||||||
|
"error-invalid-room-type": "{{type}} är inte en giltig typ av rum.",
|
||||||
|
"error-invalid-settings": "Ogiltiga inställningar har angetts",
|
||||||
|
"error-invalid-subscription": "Ogiltig prenumeration",
|
||||||
|
"error-invalid-token": "Ogiltig token",
|
||||||
|
"error-invalid-triggerWords": "Ogiltiga triggerWords",
|
||||||
|
"error-invalid-urls": "Ogiltiga URL:er",
|
||||||
|
"error-invalid-user": "Ogiltig användare",
|
||||||
|
"error-invalid-username": "Ogiltigt användarnamn",
|
||||||
|
"error-invalid-webhook-response": "Webhook-URL:en returnerade en annan status än 200",
|
||||||
|
"error-message-deleting-blocked": "Borttagande av meddelanden har blockerats",
|
||||||
|
"error-message-editing-blocked": "Redigering av meddelanden har blockerats",
|
||||||
|
"error-message-size-exceeded": "Meddelandets storlek överstiger Message_MaxAllowedSize",
|
||||||
|
"error-missing-unsubscribe-link": "Du måste ange länken [unsubscribe].",
|
||||||
|
"error-no-owner-channel": "Du äger inte kanalen",
|
||||||
|
"error-no-tokens-for-this-user": "Det finns inga token för användaren",
|
||||||
|
"error-not-allowed": "Tillåts inte",
|
||||||
|
"error-not-authorized": "Inte behörig",
|
||||||
|
"error-push-disabled": "Pushmeddelanden är inaktiverade",
|
||||||
|
"error-remove-last-owner": "Det här är den sista ägaren. Ange en ny ägare innan du tar bort den här.",
|
||||||
|
"error-role-in-use": "Det går inte att ta bort rollen eftersom den används",
|
||||||
|
"error-role-name-required": "Rollnamnet måste anges",
|
||||||
|
"error-password-same-as-current": "Lösenordet du angett är detsamma som det nuvarande lösenordet",
|
||||||
|
"error-the-field-is-required": "Fältet {{field}} är obligatoriskt.",
|
||||||
|
"error-too-many-requests": "Fel. För många begäranden. Sakta ned. Du måste vänta {{seconds}} sekunder innan du försöker igen.",
|
||||||
|
"error-user-is-not-activated": "Användaren är inte aktiverad",
|
||||||
|
"error-user-has-no-roles": "Användaren har inga roller",
|
||||||
|
"error-user-limit-exceeded": "Antalet användare som du försöker bjuda in till #channel_name överskrider gränsen som administratören har angett",
|
||||||
|
"error-user-not-in-room": "Användaren är inte i det här rummet",
|
||||||
|
"error-user-registration-custom-field": "error-user-registration-custom-field",
|
||||||
|
"error-user-registration-disabled": "Användarregistrering är inaktiverad",
|
||||||
|
"error-user-registration-secret": "Registrering av användare tillåts bara via en säker URL",
|
||||||
|
"error-you-are-last-owner": "Du är den senaste ägaren. Ange en ny ägare innan du lämnar rummet.",
|
||||||
|
"error-status-not-allowed": "Dold status är inaktiverat",
|
||||||
|
"A_new_owner_will_be_assigned_automatically_to__count__rooms": "En ny ägare utses automatiskt för {{count}} rum.",
|
||||||
|
"A_new_owner_will_be_assigned_automatically_to__count__room": "En ny ägare utses automatiskt för {{count}} rum.",
|
||||||
|
"Actions": "Åtgärder",
|
||||||
|
"Activity": "Aktivitet",
|
||||||
|
"Add_Reaction": "Lägg till reaktion",
|
||||||
|
"Add_Server": "Lägg till server",
|
||||||
|
"Add_users": "Lägg till användare",
|
||||||
|
"Admin_Panel": "Administratörspanel",
|
||||||
|
"Agent": "Agent",
|
||||||
|
"Alert": "Varning",
|
||||||
|
"alert": "varning",
|
||||||
|
"alerts": "varningar",
|
||||||
|
"All_users_in_the_channel_can_write_new_messages": "Alla användare i kanalen kan skriva nya meddelanden",
|
||||||
|
"All_users_in_the_team_can_write_new_messages": "Alla användare i teamet kan skriva nya meddelanden",
|
||||||
|
"A_meaningful_name_for_the_discussion_room": "Ett beskrivande namn på diskussionsrummet",
|
||||||
|
"All": "Alla",
|
||||||
|
"All_Messages": "Alla meddelanden",
|
||||||
|
"Allow_Reactions": "Tillåt reaktioner",
|
||||||
|
"Alphabetical": "Alfabetisk ordning",
|
||||||
|
"and_more": "med mera",
|
||||||
|
"and": "och",
|
||||||
|
"announcement": "meddelande",
|
||||||
|
"Announcement": "Meddelande",
|
||||||
|
"Apply_Your_Certificate": "Tillämpa certifikatet",
|
||||||
|
"ARCHIVE": "ARKIV",
|
||||||
|
"archive": "arkiv",
|
||||||
|
"are_typing": "skriver",
|
||||||
|
"Are_you_sure_question_mark": "Är du säker?",
|
||||||
|
"Are_you_sure_you_want_to_delete_your_account": "Vill du ta bort kontot?",
|
||||||
|
"Deleting_a_user_will_delete_all_messages": "När du tar bort en användare tas alla meddelanden, rum och team för användaren också bort. Åtgärden kan inte ångras.",
|
||||||
|
"Are_you_sure_you_want_to_leave_the_room": "Vill du lämna rummet {{room}}?",
|
||||||
|
"Audio": "Ljud",
|
||||||
|
"Authenticating": "Autentiserar",
|
||||||
|
"Automatic": "Automatiskt",
|
||||||
|
"Auto_Translate": "Automatisk översättning",
|
||||||
|
"Avatar_changed_successfully": "Avataren har ändrats",
|
||||||
|
"Avatar_Url": "URL till avatar",
|
||||||
|
"Away": "Borta",
|
||||||
|
"Back": "Tillbaka",
|
||||||
|
"Black": "Svart",
|
||||||
|
"Block_user": "Blockera användare",
|
||||||
|
"Browser": "Webbläsare",
|
||||||
|
"Busy": "Upptagen",
|
||||||
|
"By_proceeding_you_are_agreeing": "Genom att fortsätta anses du ha godkänt vår",
|
||||||
|
"Cancel_editing": "Avbryt redigering",
|
||||||
|
"Cancel_recording": "Avbryt inspelning",
|
||||||
|
"Cancel": "Avbryt",
|
||||||
|
"changing_avatar": "byter avatar",
|
||||||
|
"creating_channel": "skapar kanal",
|
||||||
|
"creating_invite": "skapar inbjudan",
|
||||||
|
"Channel_Name": "Kanalnamn",
|
||||||
|
"Channels": "Kanaler",
|
||||||
|
"Chats": "Chattar",
|
||||||
|
"Chat_started": "Chatten har startats",
|
||||||
|
"Call_already_ended": "Samtalet är redan avslutat.",
|
||||||
|
"Clear_cookies_alert": "Vill du rensa alla cookies?",
|
||||||
|
"Clear_cookies_desc": "Med den här åtgärden tas alla inloggningscookies bort så att du kan logga in på andra konton.",
|
||||||
|
"Clear_cookies_yes": "Ja, rensa cookies",
|
||||||
|
"Clear_cookies_no": "Nej, behåll cookies",
|
||||||
|
"Click_to_join": "Klicka för att ansluta.",
|
||||||
|
"Close": "Stäng",
|
||||||
|
"Close_emoji_selector": "Stäng emojiväljaren",
|
||||||
|
"Closing_chat": "Stänger chatten",
|
||||||
|
"Change_language_loading": "Ändrar språk.",
|
||||||
|
"Chat_closed_by_agent": "Chatten stängdes av agenten",
|
||||||
|
"Choose": "Välj",
|
||||||
|
"Choose_from_library": "Välj från biblioteket",
|
||||||
|
"Choose_file": "Välj fil",
|
||||||
|
"Choose_where_you_want_links_be_opened": "Välj var du vill att länkar ska öppnas",
|
||||||
|
"Code": "Kod",
|
||||||
|
"Code_or_password_invalid": "Koden eller lösenordet är ogiltigt",
|
||||||
|
"Conversation_closed": "Konversationen har stängts",
|
||||||
|
"Collaborative": "Samarbete",
|
||||||
|
"Confirm": "Bekräfta",
|
||||||
|
"Connect": "Anslut",
|
||||||
|
"Connected": "Ansluten",
|
||||||
|
"connecting_server": "ansluter till servern",
|
||||||
|
"Connecting": "Ansluter...",
|
||||||
|
"Contact_us": "Kontakta oss",
|
||||||
|
"Contact_your_server_admin": "Kontakta serveradministratören.",
|
||||||
|
"Continue_with": "Fortsätt med",
|
||||||
|
"Copied_to_clipboard": "Kopierades till urklipp.",
|
||||||
|
"Copy": "Kopiera",
|
||||||
|
"Conversation": "Konversation",
|
||||||
|
"Certificate_password": "Lösenord för certifikat",
|
||||||
|
"Clear_cache": "Rensa den lokala servercachen",
|
||||||
|
"Clear_cache_loading": "Rensar cachen.",
|
||||||
|
"Whats_the_password_for_your_certificate": "Ange lösenordet för certifikatet.",
|
||||||
|
"Create_account": "Skapa ett konto",
|
||||||
|
"Create_Channel": "Skapa kanal",
|
||||||
|
"Create_Direct_Messages": "Skapa direktmeddelande",
|
||||||
|
"Create_Discussion": "Skapa diskussion",
|
||||||
|
"Created_snippet": "skapade ett utdrag",
|
||||||
|
"Create_a_new_workspace": "Skapa en ny arbetsyta",
|
||||||
|
"Create": "Skapa",
|
||||||
|
"Custom_Status": "Anpassad status",
|
||||||
|
"Dark": "Mörk",
|
||||||
|
"Dark_level": "Mörk nivå",
|
||||||
|
"Default": "Standard",
|
||||||
|
"Default_browser": "Standardwebbläsare",
|
||||||
|
"Delete_Room_Warning": "Om du tar bort ett rum tas alla meddelanden bort som publicerats i rummet. Åtgärden kan inte ångras.",
|
||||||
|
"Department": "Avdelning",
|
||||||
|
"delete": "ta bort",
|
||||||
|
"Delete": "Ta bort",
|
||||||
|
"DELETE": "TA BORT",
|
||||||
|
"Delete_Account": "Ta bort konto",
|
||||||
|
"Delete_Account_confirm": "Ja, ta bort",
|
||||||
|
"move": "flytta",
|
||||||
|
"deleting_room": "tar bort rum",
|
||||||
|
"description": "beskrivning",
|
||||||
|
"Description": "Beskrivning",
|
||||||
|
"Desktop_Options": "Skrivbordsalternativ",
|
||||||
|
"Desktop_Notifications": "Skrivbordsaviseringar",
|
||||||
|
"Desktop_Alert_info": "De här aviseringarna levereras via skrivbordet",
|
||||||
|
"Directory": "Katalog",
|
||||||
|
"Direct_Messages": "Direktmeddelanden",
|
||||||
|
"Disable_notifications": "Inaktivera aviseringar",
|
||||||
|
"Discussions": "Diskussioner",
|
||||||
|
"Discussion_Desc": "Bidra till att skapa en översikt över det som händer. När du skapar en diskussion skapas en underkanal till den du valt och båda kanalerna är kopplade.",
|
||||||
|
"Discussion_name": "Diskussionsnamn",
|
||||||
|
"Done": "Klart",
|
||||||
|
"Dont_Have_An_Account": "Har du inget konto?",
|
||||||
|
"Do_you_have_an_account": "Har du ett konto?",
|
||||||
|
"Do_you_have_a_certificate": "Har du ett certifikat?",
|
||||||
|
"Do_you_really_want_to_key_this_room_question_mark": "Vill du verkligen {{key}} rummet?",
|
||||||
|
"E2E_Encryption": "E2E-kryptering",
|
||||||
|
"E2E_How_It_Works_info1": "Nu kan du skapa krypterade privata grupper och direktmeddelanden. Du kan också kryptera befintliga privata grupper och direktmeddelanden.",
|
||||||
|
"E2E_How_It_Works_info2": "Det här görs med *end-to-end-kryptering*, så nyckeln för att koda/avkoda meddelanden sparas inte på servern. Därför *måste du lagra lösenordet på en säker plats* där du kan åtkomma det senare om du behöver.",
|
||||||
|
"E2E_How_It_Works_info3": "Om du fortsätter genereras ett E2E-lösenord automatiskt",
|
||||||
|
"E2E_How_It_Works_info4": "Du kan när som helst ställa in ett nytt lösenord för krypteringsnyckeln i en webbläsare där du har angett det befintliga E2E-lösenordet.",
|
||||||
|
"edit": "redigera",
|
||||||
|
"edited": "redigerade",
|
||||||
|
"Edit": "Redigera",
|
||||||
|
"Edit_Status": "Redigera status",
|
||||||
|
"Edit_Invite": "Redigera inbjudan",
|
||||||
|
"End_to_end_encrypted_room": "End-to-end-krypterat rum",
|
||||||
|
"end_to_end_encryption": "End-to-end-kryptering",
|
||||||
|
"Email_Notification_Mode_All": "Varje omnämnande/direktmeddelande",
|
||||||
|
"Email_Notification_Mode_Disabled": "Inaktiverat",
|
||||||
|
"Email_or_password_field_is_empty": "Fältet för e-post eller lösenord är tomt",
|
||||||
|
"Email": "E-post",
|
||||||
|
"email": "e-post",
|
||||||
|
"Empty_title": "Tom rubrik",
|
||||||
|
"Enable_Auto_Translate": "Aktivera automatisk översättning",
|
||||||
|
"Enable_notifications": "Aktivera aviseringar",
|
||||||
|
"Encrypted": "Krypterat",
|
||||||
|
"Encrypted_message": "Krypterat meddelande",
|
||||||
|
"Enter_Your_E2E_Password": "Ange ditt E2E-lösenord",
|
||||||
|
"Enter_Your_Encryption_Password_desc1": "Det här gör att du kan komma åt dina krypterade privata grupper och direktmeddelanden.",
|
||||||
|
"Enter_Your_Encryption_Password_desc2": "Du måste ange lösenordet för att koda/avkoda meddelanden på varje plats där du använder chatten.",
|
||||||
|
"Encryption_error_title": "Ditt krypteringslösenord verkar vara felaktigt",
|
||||||
|
"Encryption_error_desc": "Det gick inte att avkoda krypteringsnyckeln som skulle importeras.",
|
||||||
|
"Everyone_can_access_this_channel": "Kanalen är öppen för alla",
|
||||||
|
"Everyone_can_access_this_team": "Teamet är öppet för alla",
|
||||||
|
"Error_uploading": "Fel vid uppladdning",
|
||||||
|
"Expiration_Days": "Förfallotid (dagar)",
|
||||||
|
"Favorites": "Favoriter",
|
||||||
|
"Files": "Filer",
|
||||||
|
"File_description": "Filbeskrivning",
|
||||||
|
"File_name": "Filnamn",
|
||||||
|
"Finish_recording": "Avsluta inspelningen",
|
||||||
|
"Following_thread": "Följer tråd",
|
||||||
|
"For_your_security_you_must_enter_your_current_password_to_continue": "För din egen säkerhet måste du ange ditt nuvarande lösenord för att fortsätta",
|
||||||
|
"Forgot_password_If_this_email_is_registered": "Om e-postadressen är registrerad skickar vi anvisningar för hur du återställer lösenordet. Om du inte får ett e-postmeddelande inom kort får du komma tillbaka och försöka igen.",
|
||||||
|
"Forgot_password": "Glömt lösenordet?",
|
||||||
|
"Forgot_Password": "Glömt lösenordet",
|
||||||
|
"Forward": "Vidarebefordra",
|
||||||
|
"Forward_Chat": "Vidarebefordra chatt",
|
||||||
|
"Forward_to_department": "Vidarebefordra till avdelning",
|
||||||
|
"Forward_to_user": "Vidarebefordra till användare",
|
||||||
|
"Full_table": "Klicka för att visa hela tabellen",
|
||||||
|
"Generate_New_Link": "Generera ny länk",
|
||||||
|
"Get_link": "Hämta länk",
|
||||||
|
"User_joined_the_channel": "anslöt till kanalen",
|
||||||
|
"User_joined_the_conversation": "anslöt till samtalet",
|
||||||
|
"User_joined_the_team": "gick med i teamet",
|
||||||
|
"User_left_this_channel": "lämnade kanalen",
|
||||||
|
"Has_left_the_team": "har lämnat kanalen",
|
||||||
|
"Hide_System_Messages": "Dölj systemmeddelanden",
|
||||||
|
"Hide_type_messages": "Dölj meddelanden av typen {{type}}",
|
||||||
|
"How_It_Works": "Så fungerar det",
|
||||||
|
"Message_HideType_uj": "Användare ansluter",
|
||||||
|
"Message_HideType_ul": "Användare lämnar",
|
||||||
|
"Message_HideType_ru": "Användare borttagen",
|
||||||
|
"Message_HideType_au": "Användare tillagd",
|
||||||
|
"Message_HideType_mute_unmute": "Användaren har tystats/ljudet har slagits på för användaren",
|
||||||
|
"Message_HideType_r": "Rummets namn har ändrats",
|
||||||
|
"Message_HideType_ut": "Användare har anslutit till samtalet",
|
||||||
|
"Message_HideType_wm": "Välkommen",
|
||||||
|
"Message_HideType_rm": "Meddelande borttaget",
|
||||||
|
"Message_HideType_subscription_role_added": "Fick rollen",
|
||||||
|
"Message_HideType_subscription_role_removed": "Rollen är inte definierad längre",
|
||||||
|
"Message_HideType_room_archived": "Rum arkiverat",
|
||||||
|
"Message_HideType_room_unarchived": "Rummet har avarkiverats",
|
||||||
|
"I_Saved_My_E2E_Password": "Jag har sparat mitt E2E-lösenord",
|
||||||
|
"IP": "IP",
|
||||||
|
"In_app": "I appen",
|
||||||
|
"In_App_And_Desktop": "I appen och på skrivbordet",
|
||||||
|
"In_App_and_Desktop_Alert_info": "En banderoll visas högst upp på skärmen och en avisering visas på skrivbordet när appen är öppen",
|
||||||
|
"Invisible": "Dold",
|
||||||
|
"Invite": "Bjud in",
|
||||||
|
"is_a_valid_RocketChat_instance": "är en giltig Rocket.Chat-instans",
|
||||||
|
"is_not_a_valid_RocketChat_instance": "är inte en giltig Rocket.Chat-instans",
|
||||||
|
"is_typing": "skriver",
|
||||||
|
"Invalid_or_expired_invite_token": "Ogiltig eller utgången inbjudningstoken",
|
||||||
|
"Invalid_server_version": "Den server du försöker ansluta till använder en version som appen inte har stöd för längre: {{currentVersion}}.\n\nDu måste ha version {{minVersion}}",
|
||||||
|
"Invite_Link": "Inbjudningslänk",
|
||||||
|
"Invite_users": "Bjud in användare",
|
||||||
|
"Join": "Gå med",
|
||||||
|
"Join_Code": "Anslutningskod",
|
||||||
|
"Insert_Join_Code": "Ange anslutningskoden",
|
||||||
|
"Join_our_open_workspace": "Anslut till vår öppna arbetsyta",
|
||||||
|
"Join_your_workspace": "Anslut till vår arbetsyta",
|
||||||
|
"Just_invited_people_can_access_this_channel": "Endast inbjudna har åtkomst till den här kanalen",
|
||||||
|
"Just_invited_people_can_access_this_team": "Endast inbjudna har åtkomst till det här teamet",
|
||||||
|
"Language": "Språk",
|
||||||
|
"last_message": "senaste meddelandet",
|
||||||
|
"Leave_channel": "Lämna kanal",
|
||||||
|
"leaving_room": "lämnar rummet",
|
||||||
|
"Leave": "Lämna",
|
||||||
|
"leave": "lämna",
|
||||||
|
"Legal": "Juridisk information",
|
||||||
|
"Light": "Ljus",
|
||||||
|
"License": "Licens",
|
||||||
|
"Livechat": "Livechatt",
|
||||||
|
"Livechat_edit": "Livechattredigering",
|
||||||
|
"Livechat_transfer_return_to_the_queue": "återförde chatten till kön",
|
||||||
|
"Login": "Logga in",
|
||||||
|
"Login_error": "Dina inloggningsuppgifter avvisades. Försök igen.",
|
||||||
|
"Login_with": "Logga in med",
|
||||||
|
"Logging_out": "Loggar ut.",
|
||||||
|
"Logout": "Logga ut",
|
||||||
|
"Max_number_of_uses": "Högsta antal användningar",
|
||||||
|
"Max_number_of_users_allowed_is_number": "Det högsta tillåtna antalet användare är {{maxUsers}}",
|
||||||
|
"members": "medlemmar",
|
||||||
|
"Members": "Medlemmar",
|
||||||
|
"Mentioned_Messages": "Omnämnda meddelanden",
|
||||||
|
"mentioned": "omnämnda",
|
||||||
|
"Mentions": "Omnämnanden",
|
||||||
|
"Message_accessibility": "Meddelande från {{user}} kl. {{time}}: {{message}}",
|
||||||
|
"Message_actions": "Åtgärder för meddelanden",
|
||||||
|
"Message_pinned": "Meddelandet har fästs",
|
||||||
|
"Message_removed": "meddelande borttaget",
|
||||||
|
"Message_starred": "Meddelandet har stjärnmarkerats",
|
||||||
|
"Message_unstarred": "Stjärnmarkering borttagen för meddelande",
|
||||||
|
"message": "meddelande",
|
||||||
|
"messages": "meddelanden",
|
||||||
|
"Message": "Meddelande",
|
||||||
|
"Messages": "Meddelanden",
|
||||||
|
"Message_Reported": "Meddelandet har anmälts",
|
||||||
|
"Microphone_Permission_Message": "Om du ska kunna skicka ljudmeddelanden behöver Rocket.Chat åtkomst till din mikrofon.",
|
||||||
|
"Microphone_Permission": "Mikrofonbehörighet",
|
||||||
|
"Mute": "Tysta",
|
||||||
|
"muted": "tystade",
|
||||||
|
"My_servers": "Mina servrar",
|
||||||
|
"N_people_reacted": "{{n}} personer reagerade",
|
||||||
|
"N_users": "{{n}} användare",
|
||||||
|
"N_channels": "{{n}} kanaler",
|
||||||
|
"Name": "Namn",
|
||||||
|
"Never": "Aldrig",
|
||||||
|
"New_chat_transfer": "Ny chattöverföring: {{agent}} återförde chatten till kön",
|
||||||
|
"New_Message": "Nytt meddelande",
|
||||||
|
"New_Password": "Nytt lösenord",
|
||||||
|
"New_Server": "Ny server",
|
||||||
|
"Next": "Nästa",
|
||||||
|
"No_files": "Inga filer",
|
||||||
|
"No_limit": "Ingen gräns",
|
||||||
|
"No_mentioned_messages": "Inga nämnda meddelanden",
|
||||||
|
"No_pinned_messages": "Inga fästa meddelanden",
|
||||||
|
"No_results_found": "Inga resultat hittades",
|
||||||
|
"No_members_found": "Inga medlemmar hittades",
|
||||||
|
"No_starred_messages": "Inga stjärnmarkerade meddelanden",
|
||||||
|
"No_thread_messages": "Inga trådmeddelanden",
|
||||||
|
"No_label_provided": "Ingen {{label}} har angetts.",
|
||||||
|
"No_Message": "Inga meddelanden",
|
||||||
|
"No_messages_yet": "Inga meddelanden ännu",
|
||||||
|
"No_Reactions": "Inga reaktioner",
|
||||||
|
"No_Read_Receipts": "Inga läskvitton",
|
||||||
|
"Not_logged": "Inte loggat",
|
||||||
|
"Not_RC_Server": "Det här är inte en Rocket.Chat-server.\n{{contact}}",
|
||||||
|
"Nothing": "Ingenting",
|
||||||
|
"Nothing_to_save": "Ingenting att spara.",
|
||||||
|
"Notify_active_in_this_room": "Meddela aktiva användare i rummet",
|
||||||
|
"Notify_all_in_this_room": "Meddela alla i rummet",
|
||||||
|
"Notifications": "Meddelanden",
|
||||||
|
"Notification_Duration": "Tidslängd för meddelande",
|
||||||
|
"Notification_Preferences": "Inställningar för meddelanden",
|
||||||
|
"No_available_agents_to_transfer": "Inga agenter att överföra till",
|
||||||
|
"Offline": "Offline",
|
||||||
|
"Oops": "Ojdå!",
|
||||||
|
"Omnichannel": "Omnichannel",
|
||||||
|
"Omnichannel_enable_alert": "Du är inte tillgänglig i Omnichannel. Vill du vara tillgänglig?",
|
||||||
|
"Onboarding_description": "En arbetsyta är en plats där ditt team eller din organisation kan samarbeta. Be arbetsyteadministratören om en adress att ansluta till eller skapa en åt teamet.",
|
||||||
|
"Onboarding_join_workspace": "Anslut till en arbetsyta",
|
||||||
|
"Onboarding_subtitle": "Mer än teamsamarbete",
|
||||||
|
"Onboarding_title": "Välkommen till Rocket.Chat",
|
||||||
|
"Onboarding_join_open_description": "Anslut till vår öppna arbetsyta där du kan chatta med Rocket.Chats team och community.",
|
||||||
|
"Onboarding_agree_terms": "Genom att fortsätta anses du ha godkänt Rocket.Chat",
|
||||||
|
"Onboarding_less_options": "Färre alternativ",
|
||||||
|
"Onboarding_more_options": "Fler alternativ",
|
||||||
|
"Online": "Online",
|
||||||
|
"Only_authorized_users_can_write_new_messages": "Endast behöriga användare kan skriva nya meddelanden",
|
||||||
|
"Open_emoji_selector": "Öppna emojiväljaren",
|
||||||
|
"Open_Source_Communication": "Kommunikation via öppen källkod",
|
||||||
|
"Open_your_authentication_app_and_enter_the_code": "Öppna autentiseringsappen och ange koden.",
|
||||||
|
"OR": "ELLER",
|
||||||
|
"OS": "Operativsystem",
|
||||||
|
"Overwrites_the_server_configuration_and_use_room_config": "Skriver över serverkonfigurationen och använder rumskonfigurationen",
|
||||||
|
"Password": "Lösenord",
|
||||||
|
"Parent_channel_or_group": "Överordnad kanal eller grupp",
|
||||||
|
"Permalink_copied_to_clipboard": "Permalänken har kopierats till urklipp.",
|
||||||
|
"Phone": "Telefonnummer",
|
||||||
|
"Pin": "Fäst",
|
||||||
|
"Pinned_Messages": "Fästa meddelanden",
|
||||||
|
"pinned": "fäst",
|
||||||
|
"Pinned": "Fästa",
|
||||||
|
"Please_add_a_comment": "Lägg till en kommentar",
|
||||||
|
"Please_enter_your_password": "Ange lösenordet",
|
||||||
|
"Please_wait": "Vänta.",
|
||||||
|
"Preferences": "Inställningar",
|
||||||
|
"Preferences_saved": "Inställningarna har sparats.",
|
||||||
|
"Privacy_Policy": "Integritetspolicy",
|
||||||
|
"Private": "Privat",
|
||||||
|
"Processing": "Bearbetar...",
|
||||||
|
"Profile_saved_successfully": "Profilen har sparats.",
|
||||||
|
"Profile": "Profil",
|
||||||
|
"Public_Channel": "Offentlig kanal",
|
||||||
|
"Public": "Offentlig",
|
||||||
|
"Push_Notifications": "Pushmeddelanden",
|
||||||
|
"Push_Notifications_Alert_Info": "De här meddelandena levereras till dig när appen är stängd",
|
||||||
|
"Quote": "Citat",
|
||||||
|
"Reactions_are_disabled": "Reaktioner är inaktiverade",
|
||||||
|
"Reactions_are_enabled": "Reaktioner är aktiverade",
|
||||||
|
"Reactions": "Reaktioner",
|
||||||
|
"Read_External_Permission_Message": "Rocket.Chat behöver åtkomst till foton, media och filer på enheten",
|
||||||
|
"Read_External_Permission": "Behörighet att läsa media",
|
||||||
|
"Read_Only": "Skrivskyddat",
|
||||||
|
"Read_Receipt": "Läskvitto",
|
||||||
|
"Receive_Group_Mentions": "Ta emot gruppomnämnanden",
|
||||||
|
"Receive_Group_Mentions_Info": "Ta emot omnämnanden av typen @all och @here",
|
||||||
|
"Register": "Registrera",
|
||||||
|
"Repeat_Password": "Upprepa lösenordet",
|
||||||
|
"Replied_on": "Svarade:",
|
||||||
|
"replies": "svar",
|
||||||
|
"reply": "svar",
|
||||||
|
"Reply": "Svara",
|
||||||
|
"Report": "Anmäl",
|
||||||
|
"Receive_Notification": "Ta emot meddelanden",
|
||||||
|
"Receive_notifications_from": "Ta emot meddelanden från {{name}}",
|
||||||
|
"Resend": "Skicka igen",
|
||||||
|
"Reset_password": "Återställ lösenordet",
|
||||||
|
"resetting_password": "återställer lösenordet",
|
||||||
|
"RESET": "ÅTERSTÄLL",
|
||||||
|
"Return_to_waiting_line": "Återgå till kön",
|
||||||
|
"Review_app_title": "Tycker du om appen?",
|
||||||
|
"Review_app_desc": "Ge oss fem stjärnor på {{store}}",
|
||||||
|
"Review_app_yes": "Visst!",
|
||||||
|
"Review_app_no": "Nej",
|
||||||
|
"Review_app_later": "Kanske senare",
|
||||||
|
"Review_app_unable_store": "Det går inte att öppna {{store}}",
|
||||||
|
"Review_this_app": "Betygsätt appen",
|
||||||
|
"Remove": "Ta bort",
|
||||||
|
"remove": "ta bort",
|
||||||
|
"Roles": "Roller",
|
||||||
|
"Room_actions": "Rumsåtgärder",
|
||||||
|
"Room_changed_announcement": "Rummets presentation har ändrats till: {{announcement}} av {{userBy}}",
|
||||||
|
"room_avatar_changed": "ändrade rummets avatar",
|
||||||
|
"Room_changed_description": "Rummets beskrivning har ändrats till: {{description}} av {{userBy}}",
|
||||||
|
"changed_room_description": "ändrade rummets beskrivning till: {{description}}",
|
||||||
|
"changed_room_announcement": "ändrade rummets presentation till: {{announcement}}",
|
||||||
|
"room_changed_type": "ändrade rummet till {{type}}",
|
||||||
|
"room_changed_topic_to": "ändrade rummets ämne till: {{topic}}",
|
||||||
|
"Room_Files": "Filer för rum",
|
||||||
|
"Room_Info_Edit": "Redigera information om rum",
|
||||||
|
"Room_Info": "Information om rum",
|
||||||
|
"Room_Members": "Rummets medlemmar",
|
||||||
|
"Room_name_changed_to": "ändrade rummets namn till: {{name}}",
|
||||||
|
"room_disallowed_reactions": "otillåtna reaktioner",
|
||||||
|
"room_allowed_reactions": "tillåtna reaktioner",
|
||||||
|
"room_removed_read_only_permission": "tog bort behörighet för skrivskyddad åtkomst",
|
||||||
|
"room_set_read_only_permission": "skrivskydda rummet",
|
||||||
|
"SAVE": "SPARA",
|
||||||
|
"Save_Changes": "Spara ändringar",
|
||||||
|
"Save": "Spara",
|
||||||
|
"Saved": "Sparade",
|
||||||
|
"saving_preferences": "sparar inställningarna",
|
||||||
|
"saving_profile": "sparar profilen",
|
||||||
|
"saving_settings": "sparar inställningarna",
|
||||||
|
"saved_to_gallery": "Sparat i galleriet",
|
||||||
|
"Save_Your_E2E_Password": "Spara ditt E2E-lösenord",
|
||||||
|
"Save_Your_Encryption_Password": "Spara ditt krypteringslösenord",
|
||||||
|
"Save_Your_Encryption_Password_warning": "Lösenordet lagras inte, så se till att spara det någon annanstans.",
|
||||||
|
"Save_Your_Encryption_Password_info": "Obs! Om du förlorar lösenordet går det inte att återställa det och du förlorar åtkomsten till alla dina meddelanden.",
|
||||||
|
"Search_Messages": "Sök bland meddelanden",
|
||||||
|
"Search": "Sök",
|
||||||
|
"Search_by": "Sök efter",
|
||||||
|
"Search_emoji": "Sök efter emoji",
|
||||||
|
"Search_global_users": "Sök efter globala användare",
|
||||||
|
"Search_global_users_description": "Om du aktiverar alternativet kan du söka efter användare från andra företag eller servrar.",
|
||||||
|
"Seconds": "{{second}} sekunder",
|
||||||
|
"Security_and_privacy": "Säkerhet och integritet",
|
||||||
|
"Select_Avatar": "Välj en avatar",
|
||||||
|
"Select_Server": "Välj server",
|
||||||
|
"Select_Users": "Välj användare",
|
||||||
|
"Select_a_Channel": "Välj en kanal",
|
||||||
|
"Select_a_Department": "Välj en avdelning",
|
||||||
|
"Select_an_option": "Välj ett alternativ",
|
||||||
|
"Select_a_User": "Välj en användare",
|
||||||
|
"Send": "Skicka",
|
||||||
|
"Send_audio_message": "Skicka ljudmeddelande",
|
||||||
|
"Send_crash_report": "Skicka kraschrapport",
|
||||||
|
"Send_message": "Skicka meddelande",
|
||||||
|
"Send_me_the_code_again": "Skicka mig koden igen",
|
||||||
|
"Send_to": "Skicka till...",
|
||||||
|
"Sending_to": "Skickar till",
|
||||||
|
"Sent_an_attachment": "Skickade en bilaga",
|
||||||
|
"Server": "Server",
|
||||||
|
"Servers": "Servrar",
|
||||||
|
"Server_version": "Serverversion: {{version}}",
|
||||||
|
"Set_username_subtitle": "Användarnamnet används till att låta andra nämna dig i meddelanden",
|
||||||
|
"Set_custom_status": "Ange anpassad status",
|
||||||
|
"Set_status": "Ange status",
|
||||||
|
"Status_saved_successfully": "Statusen har sparats.",
|
||||||
|
"Settings": "Inställningar",
|
||||||
|
"Settings_succesfully_changed": "Inställningarna har ändrats.",
|
||||||
|
"Share": "Dela",
|
||||||
|
"Share_Link": "Dela länk",
|
||||||
|
"Share_this_app": "Dela den här appen",
|
||||||
|
"Show_more": "Visa mer.",
|
||||||
|
"Sign_in_your_server": "Logga in på din server",
|
||||||
|
"Sign_Up": "Registrera dig",
|
||||||
|
"Some_field_is_invalid_or_empty": "Vissa fält är ogiltiga eller tomma",
|
||||||
|
"Sound": "Ljud",
|
||||||
|
"Star_room": "Stjärnmarkera rum",
|
||||||
|
"Star": "Stjärna",
|
||||||
|
"Starred_Messages": "Stjärnmarkerade meddelanden",
|
||||||
|
"starred": "stjärnmarkerat",
|
||||||
|
"Starred": "Stjärnmarkerat",
|
||||||
|
"Start_of_conversation": "Början på konversation",
|
||||||
|
"Start_a_Discussion": "Starta en diskussion",
|
||||||
|
"Started_discussion": "Startade en diskussion:",
|
||||||
|
"Started_call": "Samtalet startades av {{userBy}}",
|
||||||
|
"Submit": "Skicka",
|
||||||
|
"Table": "Tabell",
|
||||||
|
"Tags": "Taggar",
|
||||||
|
"Take_a_photo": "Ta ett foto",
|
||||||
|
"Take_a_video": "Spela in en video",
|
||||||
|
"Take_it": "Spela in!",
|
||||||
|
"tap_to_change_status": "tryck för att ändra status",
|
||||||
|
"Tap_to_view_servers_list": "Tryck för att visa serverlistan",
|
||||||
|
"Terms_of_Service": "Användarvillkor",
|
||||||
|
"Theme": "Tema",
|
||||||
|
"The_user_wont_be_able_to_type_in_roomName": "Användaren kan inte ange {{roomName}}",
|
||||||
|
"The_user_will_be_able_to_type_in_roomName": "Användaren kan ange {{roomName}}",
|
||||||
|
"There_was_an_error_while_action": "Ett fel inträffade vid {{action}}.",
|
||||||
|
"This_room_is_blocked": "Rummet är blockerat",
|
||||||
|
"This_room_is_read_only": "Rummet är skrivskyddat",
|
||||||
|
"Thread": "Tråd",
|
||||||
|
"Threads": "Trådar",
|
||||||
|
"Timezone": "Tidszon",
|
||||||
|
"To": "Till",
|
||||||
|
"topic": "ämne",
|
||||||
|
"Topic": "Ämne",
|
||||||
|
"Translate": "Översätt",
|
||||||
|
"Try_again": "Försök igen",
|
||||||
|
"Two_Factor_Authentication": "Tvåfaktorsautentisering",
|
||||||
|
"Type_the_channel_name_here": "Ange kanalens namn här",
|
||||||
|
"unarchive": "avarkivera",
|
||||||
|
"UNARCHIVE": "AVARKIVERA",
|
||||||
|
"Unblock_user": "Avblockera användare",
|
||||||
|
"Unfollowed_thread": "Sluta följa tråd",
|
||||||
|
"Unmute": "Slå på ljudet",
|
||||||
|
"unmuted": "slog på ljudet",
|
||||||
|
"Unpin": "Lossa",
|
||||||
|
"unread_messages": "oläst",
|
||||||
|
"Unread": "Oläst",
|
||||||
|
"Unread_on_top": "Olästa överst",
|
||||||
|
"Unstar": "Ta bort stjärnmarkering",
|
||||||
|
"Unsupported_system_message": "Systemmeddelande som inte stöds",
|
||||||
|
"Updating": "Uppdaterar...",
|
||||||
|
"Uploading": "Laddar upp",
|
||||||
|
"Upload_file_question_mark": "Ladda upp fil?",
|
||||||
|
"User": "Användare",
|
||||||
|
"Users": "Användare",
|
||||||
|
"User_added_to": "lade till {{userAdded}}",
|
||||||
|
"User_Info": "Användarinfo",
|
||||||
|
"User_has_been_key": "Användaren har {{key}}",
|
||||||
|
"User_is_no_longer_role_by_": "{{user}} har inte längre rollen {{role}} per {{userBy}}",
|
||||||
|
"User_has_been_muted": "tystade {{userMuted}}",
|
||||||
|
"User_has_been_removed": "tog bort {{userRemoved}}",
|
||||||
|
"User_sent_an_attachment": "{{user}} skickade en bilaga",
|
||||||
|
"User_has_been_unmuted": "slog på ljudet för {{userUnmuted}}",
|
||||||
|
"Defined_user_as_role": "angav {{user}} som {{role}}",
|
||||||
|
"Removed_user_as_role": "tog bort {{user}} som {{role}}",
|
||||||
|
"Username_is_empty": "Användarnamnet har inte angetts",
|
||||||
|
"Username": "Användarnamn",
|
||||||
|
"Username_or_email": "Användarnamn eller e-postadress",
|
||||||
|
"Uses_server_configuration": "Använder serverkonfiguration",
|
||||||
|
"Validating": "Validerar",
|
||||||
|
"Registration_Succeeded": "Registreringen är klar.",
|
||||||
|
"Verify": "Verifiera",
|
||||||
|
"Verify_email_title": "Registreringen är klar.",
|
||||||
|
"Verify_email_desc": "Vi har skickat ett e-postmeddelande för att bekräfta din registrering. Om du inte får e-postmeddelandet försöker du igen.",
|
||||||
|
"Verify_your_email_for_the_code_we_sent": "Titta efter koden i din e-post",
|
||||||
|
"Video_call": "Videosamtal",
|
||||||
|
"View_Original": "Visa original",
|
||||||
|
"Voice_call": "Röstsamtal",
|
||||||
|
"Waiting_for_network": "Väntar på nätverket...",
|
||||||
|
"Websocket_disabled": "Websocket är inaktiverad för servern.\n{{contact}}",
|
||||||
|
"Welcome": "Välkommen",
|
||||||
|
"What_are_you_doing_right_now": "Vad gör du just nu?",
|
||||||
|
"Whats_your_2fa": "Vilken är din kod för tvåfaktorsautentisering?",
|
||||||
|
"Without_Servers": "Utan servrar",
|
||||||
|
"Workspaces": "Arbetsytor",
|
||||||
|
"Would_you_like_to_return_the_inquiry": "Vill du skicka tillbaka förfrågan?",
|
||||||
|
"Write_External_Permission_Message": "Rocket.Chat behöver åtkomst till ditt galleri så att du kan spara bilder.",
|
||||||
|
"Write_External_Permission": "Galleribehörighet",
|
||||||
|
"Yes": "Ja",
|
||||||
|
"Yes_action_it": "Ja, {{action}}!",
|
||||||
|
"Yesterday": "Igår",
|
||||||
|
"You_are_in_preview_mode": "Du är i förhandsgranskningsläge",
|
||||||
|
"You_are_offline": "Du är offline",
|
||||||
|
"You_can_search_using_RegExp_eg": "Du kan använda reguljära uttryck, till exempel /^text$/i",
|
||||||
|
"You_colon": "Du:",
|
||||||
|
"you_were_mentioned": "du nämndes",
|
||||||
|
"You_were_removed_from_channel": "Du togs bort från {{channel}}",
|
||||||
|
"you": "du",
|
||||||
|
"You": "Du",
|
||||||
|
"Logged_out_by_server": "Du har loggats ut av servern. Logga in på nytt.",
|
||||||
|
"Token_expired": "Din session har upphört. Logga in igen.",
|
||||||
|
"You_need_to_access_at_least_one_RocketChat_server_to_share_something": "Du behöver åtkomst till åtminstone en Rocket.Chat-server för att kunna dela.",
|
||||||
|
"You_need_to_verifiy_your_email_address_to_get_notications": "Du måste bekräfta din e-postadress för att få meddelanden",
|
||||||
|
"Your_certificate": "Ditt certifikat",
|
||||||
|
"Your_invite_link_will_expire_after__usesLeft__uses": "Inbjudningslänken upphör att gälla efter {{usesLeft}} användningar.",
|
||||||
|
"Your_invite_link_will_expire_on__date__or_after__usesLeft__uses": "Inbjudningslänken upphör att gälla den {{date}} eller efter {{usesLeft}} användningar.",
|
||||||
|
"Your_invite_link_will_expire_on__date__": "Inbjudningslänken upphör att gälla den {{date}}.",
|
||||||
|
"Your_invite_link_will_never_expire": "Inbjudningslänken upphör aldrig att gälla.",
|
||||||
|
"Your_workspace": "Din arbetsyta",
|
||||||
|
"Your_password_is": "Ditt lösenord är",
|
||||||
|
"Version_no": "Version: {{version}}",
|
||||||
|
"You_will_not_be_able_to_recover_this_message": "Du kan inte återställa meddelandet senare.",
|
||||||
|
"You_will_unset_a_certificate_for_this_server": "Du tar bort ett certifikat för servern",
|
||||||
|
"Change_Language": "Ändra språk",
|
||||||
|
"Crash_report_disclaimer": "Vi spårar aldrig innehållet i chattar. Kraschrapporten och analyshändelserna innehåller bara information som vi behöver för att kunna identifiera och åtgärda fel.",
|
||||||
|
"Type_message": "Skriv meddelande",
|
||||||
|
"Room_search": "Sök efter rum",
|
||||||
|
"Room_selection": "Val av rum: 1 till 9",
|
||||||
|
"Next_room": "Nästa rum",
|
||||||
|
"Previous_room": "Föregående rum",
|
||||||
|
"New_room": "Nytt rum",
|
||||||
|
"Upload_room": "Ladda upp till rum",
|
||||||
|
"Search_messages": "Sök efter meddelanden",
|
||||||
|
"Scroll_messages": "Bläddra bland meddelanden",
|
||||||
|
"Reply_latest": "Svara på senaste",
|
||||||
|
"Reply_in_Thread": "Svara i tråden",
|
||||||
|
"Server_selection": "Val av server",
|
||||||
|
"Server_selection_numbers": "Val av server: 1 till 9",
|
||||||
|
"Add_server": "Lägg till server",
|
||||||
|
"New_line": "Ny rad",
|
||||||
|
"You_will_be_logged_out_of_this_application": "Du loggas ut från programmet",
|
||||||
|
"Clear": "Rensa",
|
||||||
|
"This_will_clear_all_your_offline_data": "Med den här åtgärden rensas alla dina offlinedata.",
|
||||||
|
"This_will_remove_all_data_from_this_server": "Med den här åtgärden tas alla data bort från servern.",
|
||||||
|
"Mark_unread": "Markera som oläst",
|
||||||
|
"Wait_activation_warning": "Innan du kan logga in måste ditt konto aktiveras manuellt av en administratör.",
|
||||||
|
"Screen_lock": "Skärmlås",
|
||||||
|
"Local_authentication_biometry_title": "Autentisering",
|
||||||
|
"Local_authentication_biometry_fallback": "Använd lösenkod",
|
||||||
|
"Local_authentication_unlock_option": "Lås upp med lösenkod",
|
||||||
|
"Local_authentication_change_passcode": "Ändra lösenkod",
|
||||||
|
"Local_authentication_info": "Obs! Om du glömmer bort lösenkoden måste du ta bort och sedan installera appen på nytt.",
|
||||||
|
"Local_authentication_facial_recognition": "ansiktsigenkänning",
|
||||||
|
"Local_authentication_fingerprint": "fingeravtryck",
|
||||||
|
"Local_authentication_unlock_with_label": "Lås upp med {{label}}",
|
||||||
|
"Local_authentication_auto_lock_60": "Efter 1 minut",
|
||||||
|
"Local_authentication_auto_lock_300": "Efter 5 minuter",
|
||||||
|
"Local_authentication_auto_lock_900": "Efter 15 minuter",
|
||||||
|
"Local_authentication_auto_lock_1800": "Efter 30 minuter",
|
||||||
|
"Local_authentication_auto_lock_3600": "Efter 1 timme",
|
||||||
|
"Passcode_enter_title": "Ange din lösenkod",
|
||||||
|
"Passcode_choose_title": "Välj en ny lösenkod",
|
||||||
|
"Passcode_choose_confirm_title": "Bekräfta den nya lösenkoden",
|
||||||
|
"Passcode_choose_error": "Lösenkoderna matchar inte. Försök igen.",
|
||||||
|
"Passcode_choose_force_set": "En lösenkod krävs av administratören",
|
||||||
|
"Passcode_app_locked_title": "Appen har låsts",
|
||||||
|
"Passcode_app_locked_subtitle": "Försök igen om {{timeLeft}} sekunder",
|
||||||
|
"After_seconds_set_by_admin": "Efter {{seconds}} sekunder (anges av administratören)",
|
||||||
|
"Dont_activate": "Aktivera inte nu",
|
||||||
|
"Queued_chats": "Köplacerade chattar",
|
||||||
|
"Logout_from_other_logged_in_locations": "Logga ut från andra platser där du är inloggad",
|
||||||
|
"You_will_be_logged_out_from_other_locations": "Du loggas ut från andra platser.",
|
||||||
|
"Logged_out_of_other_clients_successfully": "Du har loggats ut från andra klienter",
|
||||||
|
"Logout_failed": "Det gick inte att logga ut.",
|
||||||
|
"Log_analytics_events": "Logga analyshändelser",
|
||||||
|
"E2E_encryption_change_password_title": "Ändra krypteringslösenord",
|
||||||
|
"E2E_encryption_change_password_description": "Nu kan du skapa krypterade privata grupper och direktmeddelanden. Du kan också kryptera befintliga privata grupper och direktmeddelande. \nHär används end-to-end-kryptering, så nyckeln för att koda/avkoda dina meddelanden sparas inte på servern. Därför måste du spara ditt lösenord på en säker plats. Du behöver ange den på andra enheter som du vill använda end-to-end-kryptering på.",
|
||||||
|
"E2E_encryption_change_password_error": "Ett fel inträffade när lösenordet för E2E-nyckeln skulle ändras.",
|
||||||
|
"E2E_encryption_change_password_success": "Lösenordet för E2E-nyckeln har ändrats.",
|
||||||
|
"E2E_encryption_change_password_message": "Se till att spara det på en säker plats.",
|
||||||
|
"E2E_encryption_change_password_confirmation": "Ja, ändra",
|
||||||
|
"E2E_encryption_reset_title": "Återställ E2E-nyckel",
|
||||||
|
"E2E_encryption_reset_description": "Med det här alternativet tas din aktuella E2E-nyckel bort och du loggas ut. \nNär du loggar in igen genererar Rocket.Chat en ny nyckel åt dig och återställer din åtkomst till krypterade rum för vilka en eller flera aktiva medlemmar är online. \nPå grund av hur E2E-krypteringen fungerar kan Rocket.Chat inte återställa åtkomsten till krypterade rum som inte har medlemmar online.",
|
||||||
|
"E2E_encryption_reset_button": "Återställ E2E-nyckel",
|
||||||
|
"E2E_encryption_reset_error": "Fel vid återställning av E2E-nyckel.",
|
||||||
|
"E2E_encryption_reset_message": "Du loggas ut.",
|
||||||
|
"E2E_encryption_reset_confirmation": "Ja, återställ",
|
||||||
|
"Following": "Följer",
|
||||||
|
"Threads_displaying_all": "Visar alla",
|
||||||
|
"Threads_displaying_following": "Visar de du följer",
|
||||||
|
"Threads_displaying_unread": "Visar olästa",
|
||||||
|
"No_threads": "Det finns inga trådar",
|
||||||
|
"No_threads_following": "Du följer inte några trådar",
|
||||||
|
"No_threads_unread": "Det finns inga olästa trådar",
|
||||||
|
"Messagebox_Send_to_channel": "Skicka till kanal",
|
||||||
|
"Leader": "Ledare",
|
||||||
|
"Moderator": "Moderator",
|
||||||
|
"Owner": "Ägare",
|
||||||
|
"Remove_from_room": "Ta bort från rummet",
|
||||||
|
"Ignore": "Ignorera",
|
||||||
|
"Unignore": "Sluta ignorera",
|
||||||
|
"User_has_been_ignored": "Användaren ignoreras",
|
||||||
|
"User_has_been_unignored": "Användaren ignoreras inte längre",
|
||||||
|
"User_has_been_removed_from_s": "Användaren har tagits bort från {{s}}",
|
||||||
|
"User__username__is_now_a_leader_of__room_name_": "Användaren {{username}} är nu ledare för {{room_name}}",
|
||||||
|
"User__username__is_now_a_moderator_of__room_name_": "Användaren {{username}} är nu moderator för{{room_name}}",
|
||||||
|
"User__username__is_now_a_owner_of__room_name_": "Användaren {{username}} är nu ägare av {{room_name}}",
|
||||||
|
"User__username__removed_from__room_name__leaders": "Användaren {{username}} har tagits bort som en av ledarna för {{room_name}}",
|
||||||
|
"User__username__removed_from__room_name__moderators": "Användaren {{username}} har tagits bort som en av moderatorerna för {{room_name}}",
|
||||||
|
"User__username__removed_from__room_name__owners": "Användaren {{username}} har tagits bort som en av ägarna av {{room_name}}",
|
||||||
|
"The_user_will_be_removed_from_s": "Användaren tas bort från {{s}}",
|
||||||
|
"Yes_remove_user": "Ja. Ta bort användaren.",
|
||||||
|
"Direct_message": "Direktmeddelande",
|
||||||
|
"Message_Ignored": "Meddelandet har ignorerats. Tryck på det om du vill visa det.",
|
||||||
|
"Enter_workspace_URL": "Ange arbetsytans URL",
|
||||||
|
"Workspace_URL_Example": "Till exempel ditt-foretag.rocket.chat",
|
||||||
|
"Enabled_E2E_Encryption_for_this_room": "aktivera E2E-kryptering för det här rummet",
|
||||||
|
"Disabled_E2E_Encryption_for_this_room": "inaktivera E2E-kryptering för det här rummet",
|
||||||
|
"Teams": "Team",
|
||||||
|
"No_team_channels_found": "Inga kanaler hittades",
|
||||||
|
"Team_not_found": "Teamet hittades inte",
|
||||||
|
"Create_Team": "Skapa team",
|
||||||
|
"Team_Name": "Teamnamn",
|
||||||
|
"creating_team": "skapar team",
|
||||||
|
"team-name-already-exists": "Det finns redan ett team med det namnet",
|
||||||
|
"Add_Channel_to_Team": "Lägg till kanal för team",
|
||||||
|
"Left_The_Team_Successfully": "Lämnade teamet",
|
||||||
|
"Create_New": "Skapa ny",
|
||||||
|
"Add_Existing": "Lägg till befintlig",
|
||||||
|
"Add_Existing_Channel": "Lägg till befintlig kanal",
|
||||||
|
"Remove_from_Team": "Ta bort från team",
|
||||||
|
"Auto-join": "Anslut automatiskt",
|
||||||
|
"Remove_Team_Room_Warning": "Vill du ta bort kanalen från teamet? Kanalen flyttas tillbaka till arbetsytan",
|
||||||
|
"Confirmation": "Bekräftelse",
|
||||||
|
"invalid-room": "Ogiltigt rum",
|
||||||
|
"You_are_leaving_the_team": "Du lämnar teamet {{team}}",
|
||||||
|
"Leave_Team": "Lämna team",
|
||||||
|
"Select_Team": "Välj team",
|
||||||
|
"Select_Team_Channels": "Välj de teamkanaler du vill lämna.",
|
||||||
|
"Cannot_leave": "Kan inte lämna",
|
||||||
|
"Cannot_remove": "Kan inte ta bort",
|
||||||
|
"Cannot_delete": "Kan inte ta bort",
|
||||||
|
"Last_owner_team_room": "Du är den sista ägaren av kanalen. När du har lämnat teamet behålls kanalen i teamet, men du får hantera den utifrån.",
|
||||||
|
"last-owner-can-not-be-removed": "Den sista ägaren kan inte tas bort",
|
||||||
|
"Remove_User_Teams": "Välj de kanaler du vill ta bort användaren från.",
|
||||||
|
"Deleting_account": "Tar bort kontot",
|
||||||
|
"Delete_my_account": "Ta bort mitt konto",
|
||||||
|
"Delete_Team": "Ta bort team",
|
||||||
|
"Select_channels_to_delete": "Åtgärden kan inte ångras. När du tar bort ett team tas allt chattinnehåll och alla inställningar bort. \n\nVälj de kanaler du vill ta bort. De du bestämmer dig för att behålla är tillgängliga i arbetsytan. Tänk på att offentliga kanaler fortfarande är offentliga och synliga för alla.",
|
||||||
|
"You_are_deleting_the_team": "Du håller på att ta bort det här teamet.",
|
||||||
|
"Removing_user_from_this_team": "Du tar bort {{user}} från det här teamet",
|
||||||
|
"Remove_User_Team_Channels": "Välj de kanaler du vill ta bort användaren från.",
|
||||||
|
"Remove_Member": "Ta bort medlem",
|
||||||
|
"leaving_team": "lämnar team",
|
||||||
|
"removing_team": "tar bort från team",
|
||||||
|
"moving_channel_to_team": "flyttar kanal till team",
|
||||||
|
"deleting_team": "tar bort team",
|
||||||
|
"member-does-not-exist": "Medlemmen finns inte",
|
||||||
|
"Convert": "Konvertera",
|
||||||
|
"Convert_to_Team": "Konvertera till team",
|
||||||
|
"Convert_to_Team_Warning": "Du konverterar kanalen till ett team. Alla medlemmar behålls.",
|
||||||
|
"Move_to_Team": "Flytta till team",
|
||||||
|
"Move_Channel_Paragraph": "Om du flyttar in en kanal i ett team läggs kanalen till i teamets kontext. Alla kanalmedlemmar som inte är medlemmar i respektive team har dock fortfarande åtkomst till kanalen, men läggs inte till som teammedlemmar. \n\nAll kanalhantering görs fortfarande av kanalens ägare.\n\nTeammedlemmar och teamägare som inte är medlemmar i kanalen får inte ha åtkomst till kanalens innehåll. \n\nObs! Teamets ägare kan ta bort medlemmar från kanalen.",
|
||||||
|
"Move_to_Team_Warning": "Vill du fortfarande flytta kanalen till det valda teamet nu när du har läst informationen om den här funktionen?",
|
||||||
|
"Load_More": "Läs in fler",
|
||||||
|
"Load_Newer": "Läs in nyare",
|
||||||
|
"Load_Older": "Läs in äldre",
|
||||||
|
"room-name-already-exists": "Rummets namn används redan",
|
||||||
|
"error-team-creation": "Ett fel inträffade när teamet skulle skapas",
|
||||||
|
"unauthorized": "Obehörig",
|
||||||
|
"Left_The_Room_Successfully": "Lämnade rummet",
|
||||||
|
"Deleted_The_Team_Successfully": "Teamet har tagits bort",
|
||||||
|
"Deleted_The_Room_Successfully": "Rummet har tagits bort",
|
||||||
|
"Convert_to_Channel": "Konvertera till kanal",
|
||||||
|
"Converting_Team_To_Channel": "Konverterar team till kanal",
|
||||||
|
"Select_Team_Channels_To_Delete": "Välj den teamkanal du vill ta bort. De du inte väljer flyttas till arbetsytan. \n\nTänk på att offentliga kanaler är öppna och synliga för alla.",
|
||||||
|
"You_are_converting_the_team": "Du konverterar det här teamet till en kanal",
|
||||||
|
"Display": "Visa",
|
||||||
|
"Avatars": "Avatarer",
|
||||||
|
"Sort_by": "Sortera per",
|
||||||
|
"Group_by": "Gruppera per",
|
||||||
|
"Types": "Typer",
|
||||||
|
"Expanded": "Expanderade",
|
||||||
|
"Condensed": "Komprimerade",
|
||||||
|
"creating_discussion": "skapar diskussion",
|
||||||
|
"Canned_Responses": "Standardsvar",
|
||||||
|
"No_match_found": "Inga resultat hittades.",
|
||||||
|
"No_discussions": "Inga diskussioner",
|
||||||
|
"Check_canned_responses": "Kontrollera standardsvar.",
|
||||||
|
"Searching": "Söker",
|
||||||
|
"Use": "Använd",
|
||||||
|
"Shortcut": "Genväg",
|
||||||
|
"Content": "Innehåll",
|
||||||
|
"Sharing": "Delar",
|
||||||
|
"No_canned_responses": "Inga standardsvar",
|
||||||
|
"Send_email_confirmation": "Skicka e-postbekräftelse",
|
||||||
|
"sending_email_confirmation": "skickar e-postbekräftelse",
|
||||||
|
"Enable_Message_Parser": "Aktivera meddelandetolken",
|
||||||
|
"Unsupported_format": "Format som inte stöds",
|
||||||
|
"Downloaded_file": "Nedladdad fil",
|
||||||
|
"Error_Download_file": "Fel vid nedladdning av fil",
|
||||||
|
"added__roomName__to_this_team": "lade till #{{roomName}} till teamet",
|
||||||
|
"Added__username__to_this_team": "lade till @{{user_added}} i teamet",
|
||||||
|
"Converting_team_to_channel": "Konverterar team till kanal",
|
||||||
|
"Converted__roomName__to_a_team": "konverterade #{{roomName}} till ett team",
|
||||||
|
"Converted__roomName__to_a_channel": "konverterade #{{roomName}} till kanal",
|
||||||
|
"Deleted__roomName__": "tog bort #{{roomName}}",
|
||||||
|
"Message_HideType_added_user_to_team": "Dölj meddelandet \"Användare lades till i teamet\"",
|
||||||
|
"Message_HideType_removed_user_from_team": "Dölj meddelandet \"Användare togs bort från teamet\"",
|
||||||
|
"Message_HideType_ujt": "Dölj meddelandet \"Användare anslöt till teamet\"",
|
||||||
|
"Message_HideType_ult": "Dölj meddelandet \"Användare lämnade teamet\"",
|
||||||
|
"Message_HideType_user_added_room_to_team": "Dölj meddelandet \"Användaren lade till rummet till teamet\"",
|
||||||
|
"Message_HideType_user_converted_to_channel": "Dölj meddelandet \"Användaren konverterade teamet till en kanal\"",
|
||||||
|
"Message_HideType_user_converted_to_team": "Dölj meddelandet \"Användaren konverterade kanalen till ett team\"",
|
||||||
|
"Message_HideType_user_deleted_room_from_team": "Dölj meddelandet \"Användaren tog bort rummet från teamet\"",
|
||||||
|
"Message_HideType_user_removed_room_from_team": "Dölj meddelandet \"Användaren tog bort rummet från teamet\"",
|
||||||
|
"Removed__roomName__from_the_team": "tog bort #{{roomName}} från teamet",
|
||||||
|
"Removed__username__from_the_team": "tog bort @{{userRemoved}} från teamet",
|
||||||
|
"User_joined_team": "anslöt till teamet",
|
||||||
|
"User_left_team": "lämnade teamet",
|
||||||
|
"Place_chat_on_hold": "Parkera chatten",
|
||||||
|
"Would_like_to_place_on_hold": "Vill du parkera chatten?",
|
||||||
|
"Open_Livechats": "Pågående Omnichannel-chattar",
|
||||||
|
"On_hold_Livechats": "Parkerade Omnichannel-chattar",
|
||||||
|
"Chat_is_on_hold": "Den här chatten är parkerad på grund av inaktivitet",
|
||||||
|
"Resume": "Återuppta",
|
||||||
|
"Omnichannel_placed_chat_on_hold": "Parkerad chatt: {{comment}}",
|
||||||
|
"Omnichannel_on_hold_chat_resumed": "Återupptog parkerad chatt: {{comment}}",
|
||||||
|
"Omnichannel_queue": "Omnichannel-kö",
|
||||||
|
"Empty": "Tom",
|
||||||
|
"Mark_as_unread": "Markera som oläst",
|
||||||
|
"Mark_as_unread_Info": "Visa rummet som oläst när det finns olästa meddelanden",
|
||||||
|
"Show_badge_for_mentions": "Visa märke för omnämnanden",
|
||||||
|
"Show_badge_for_mentions_Info": "Visa endast märke för direkta omnämnanden",
|
||||||
|
"error-init-video-conf": "Ett fel inträffade när videosamtalet skulle startas",
|
||||||
|
"totp-invalid": "Koden eller lösenordet är ogiltigt",
|
||||||
|
"Close_Chat": "Stäng chatt",
|
||||||
|
"Select_tags": "Välj taggar",
|
||||||
|
"Skip": "Hoppa över",
|
||||||
|
"N_Selected_members": "{{n}} har valts",
|
||||||
|
"Broadcast": "Sändning",
|
||||||
|
"Broadcast_hint": "Det är bara behöriga användare som kan skriva nya meddelanden, men alla andra användare kan svara",
|
||||||
|
"Team_hint_private": "Endast inbjudna personer kan ansluta",
|
||||||
|
"Team_hint_public": "När alternativet är inaktiverat kan vem som helst ansluta till teamet",
|
||||||
|
"Team_hint_not_read_only": "Alla användare i teamet kan skriva meddelanden",
|
||||||
|
"Team_hint_encrypted": "End-to-end-krypterat team. Sökfunktionen fungerar inte med krypterade team och innehållet i meddelanden kanske inte visas.",
|
||||||
|
"Team_hint_encrypted_not_available": "Endast tillgängligt för privata team",
|
||||||
|
"Channel_hint_private": "Endast inbjudna användare kan öppna kanalen",
|
||||||
|
"Channel_hint_public": "Alla kan öppna kanalen",
|
||||||
|
"Channel_hint_encrypted": "End-to-end-krypterad kanal. Sökfunktionen fungerar inte med krypterade kanaler och innehållet i meddelanden kanske inte visas.",
|
||||||
|
"Channel_hint_not_read_only": "Alla användare i kanalen kan skriva meddelanden",
|
||||||
|
"Channel_hint_encrypted_not_available": "Inte tillgängligt för offentliga kanaler",
|
||||||
|
"Read_only_hint": "Endast behöriga användare kan skriva nya meddelanden",
|
||||||
|
"Discussion": "Diskussion",
|
||||||
|
"Channel": "Kanal",
|
||||||
|
"Team": "Team",
|
||||||
|
"Select_Members": "Välj medlemmar",
|
||||||
|
"Also_send_thread_message_to_channel_behavior": "Skicka även trådmeddelande till kanalen",
|
||||||
|
"Accounts_Default_User_Preferences_alsoSendThreadToChannel_Description": "Tillåt användare att välja alternativet Skicka även till kanal",
|
||||||
|
"Waiting_for_answer": "Väntar på svar",
|
||||||
|
"Call_ended": "Samtal avslutat",
|
||||||
|
"Call_was_not_answered": "Samtalet besvarades inte",
|
||||||
|
"Call_back": "Ring upp",
|
||||||
|
"Call_again": "Ring igen",
|
||||||
|
"Call_ongoing": "Samtal pågår",
|
||||||
|
"Joined": "Anslöt",
|
||||||
|
"Calling": "Ringer upp...",
|
||||||
|
"Start_a_call": "Starta ett samtal",
|
||||||
|
"Call": "Ring",
|
||||||
|
"Reply_in_direct_message": "Svara med direktmeddelande",
|
||||||
|
"room_archived": "arkiverade rum",
|
||||||
|
"room_unarchived": "avarkiverade rum"
|
||||||
|
}
|
|
@ -302,6 +302,7 @@
|
||||||
"Message_accessibility": "{{user}} tarafından {{time}} itibarıyla ileti: {{message}}",
|
"Message_accessibility": "{{user}} tarafından {{time}} itibarıyla ileti: {{message}}",
|
||||||
"Message_actions": "İleti işlemleri",
|
"Message_actions": "İleti işlemleri",
|
||||||
"Message_pinned": "İleti sabitlendi",
|
"Message_pinned": "İleti sabitlendi",
|
||||||
|
"Message_removed": "İleti kaldırıldı",
|
||||||
"Message_starred": "İletia yıldız eklendi",
|
"Message_starred": "İletia yıldız eklendi",
|
||||||
"Message_unstarred": "İletiın yıldızı kaldırıldı",
|
"Message_unstarred": "İletiın yıldızı kaldırıldı",
|
||||||
"message": "ileti",
|
"message": "ileti",
|
||||||
|
@ -668,5 +669,6 @@
|
||||||
"Enter_workspace_URL": "Çalışma alanı URL'nizi girin",
|
"Enter_workspace_URL": "Çalışma alanı URL'nizi girin",
|
||||||
"Workspace_URL_Example": "Örn. sirketiniz.rocket.chat",
|
"Workspace_URL_Example": "Örn. sirketiniz.rocket.chat",
|
||||||
"invalid-room": "Geçersiz oda",
|
"invalid-room": "Geçersiz oda",
|
||||||
|
"Open_Livechats": "Devam Eden Sohbetler",
|
||||||
"Broadcast_hint": "Yalnızca yetkili kullanıcılar yeni ileti yazabilir, ancak diğer kullanıcılar yanıt verebilir"
|
"Broadcast_hint": "Yalnızca yetkili kullanıcılar yeni ileti yazabilir, ancak diğer kullanıcılar yanıt verebilir"
|
||||||
}
|
}
|
|
@ -177,6 +177,8 @@
|
||||||
"delete": "刪除",
|
"delete": "刪除",
|
||||||
"Delete": "刪除",
|
"Delete": "刪除",
|
||||||
"DELETE": "刪除",
|
"DELETE": "刪除",
|
||||||
|
"Delete_Account": "刪除帳號",
|
||||||
|
"Delete_Account_confirm": "是的,請刪除",
|
||||||
"deleting_room": "正在刪除聊天室",
|
"deleting_room": "正在刪除聊天室",
|
||||||
"description": "描述",
|
"description": "描述",
|
||||||
"Description": "描述",
|
"Description": "描述",
|
||||||
|
@ -222,6 +224,7 @@
|
||||||
"Encryption_error_title": "您的加密密碼似乎有誤",
|
"Encryption_error_title": "您的加密密碼似乎有誤",
|
||||||
"Encryption_error_desc": "無法使用匯入的加密金鑰來解密",
|
"Encryption_error_desc": "無法使用匯入的加密金鑰來解密",
|
||||||
"Everyone_can_access_this_channel": "所有人皆可存取此頻道",
|
"Everyone_can_access_this_channel": "所有人皆可存取此頻道",
|
||||||
|
"Everyone_can_access_this_team": "所有人皆可存取此團隊",
|
||||||
"Error_uploading": "錯誤上傳",
|
"Error_uploading": "錯誤上傳",
|
||||||
"Expiration_Days": "到期 (日)",
|
"Expiration_Days": "到期 (日)",
|
||||||
"Favorites": "我的最愛",
|
"Favorites": "我的最愛",
|
||||||
|
@ -301,6 +304,7 @@
|
||||||
"Message_accessibility": "{{time}}來自{{user}}的訊息: {{message}}",
|
"Message_accessibility": "{{time}}來自{{user}}的訊息: {{message}}",
|
||||||
"Message_actions": "訊息操作",
|
"Message_actions": "訊息操作",
|
||||||
"Message_pinned": "訊息被釘選",
|
"Message_pinned": "訊息被釘選",
|
||||||
|
"Message_removed": "訊息被刪除",
|
||||||
"Message_starred": "訊息被標註",
|
"Message_starred": "訊息被標註",
|
||||||
"Message_unstarred": "訊息被取消標註",
|
"Message_unstarred": "訊息被取消標註",
|
||||||
"message": "訊息",
|
"message": "訊息",
|
||||||
|
@ -650,5 +654,6 @@
|
||||||
"Messagebox_Send_to_channel": "發送至頻道",
|
"Messagebox_Send_to_channel": "發送至頻道",
|
||||||
"Confirmation": "確認",
|
"Confirmation": "確認",
|
||||||
"invalid-room": "無效的房間",
|
"invalid-room": "無效的房間",
|
||||||
|
"Open_Livechats": "打開即時聊天",
|
||||||
"Broadcast_hint": "只有經過授權的使用者才能發送新訊息,但其他使用者可以回覆"
|
"Broadcast_hint": "只有經過授權的使用者才能發送新訊息,但其他使用者可以回覆"
|
||||||
}
|
}
|
|
@ -1,15 +1,20 @@
|
||||||
const localeKeys: { [key: string]: string } = {
|
const localeKeys: { [key: string]: string } = {
|
||||||
en: 'en',
|
en: 'en',
|
||||||
ru: 'ru',
|
ar: 'ar',
|
||||||
'pt-BR': 'pt-br',
|
|
||||||
'zh-CN': 'zh-cn',
|
|
||||||
fr: 'fr',
|
|
||||||
de: 'de',
|
de: 'de',
|
||||||
'pt-PT': 'pt',
|
'es-ES': 'es',
|
||||||
|
fi: 'fi',
|
||||||
|
fr: 'fr',
|
||||||
it: 'it',
|
it: 'it',
|
||||||
ja: 'ja',
|
ja: 'ja',
|
||||||
nl: 'nl',
|
nl: 'nl',
|
||||||
'es-ES': 'es',
|
'pt-BR': 'pt-br',
|
||||||
|
'pt-PT': 'pt',
|
||||||
|
ru: 'ru',
|
||||||
|
'sl-SI': 'sl',
|
||||||
|
sv: 'sv',
|
||||||
|
tr: 'tr',
|
||||||
|
'zh-CN': 'zh-cn',
|
||||||
'zh-TW': 'zh-tw'
|
'zh-TW': 'zh-tw'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,22 @@ export const colors = {
|
||||||
collapsibleQuoteBorder: '#CBCED1',
|
collapsibleQuoteBorder: '#CBCED1',
|
||||||
collapsibleChevron: '#6C727A',
|
collapsibleChevron: '#6C727A',
|
||||||
cancelButton: '#E4E7EA',
|
cancelButton: '#E4E7EA',
|
||||||
|
conferenceCallBorder: '#F2F3F5',
|
||||||
|
conferenceCallBackground: '#F7F8FA',
|
||||||
|
conferenceCallOngoingPhoneBackground: '#C0F6E4',
|
||||||
|
conferenceCallIncomingPhoneBackground: '#D1EBFE',
|
||||||
|
conferenceCallEndedPhoneBackground: '#E4E7EA',
|
||||||
|
conferenceCallOngoingPhoneIcon: '#158D65',
|
||||||
|
conferenceCallIncomingPhoneIcon: '#095AD2',
|
||||||
|
conferenceCallEndedPhoneIcon: '#6C727A',
|
||||||
|
conferenceCallPlusUsersButton: '#E4E7EA',
|
||||||
|
conferenceCallPlusUsersText: '#6C727A',
|
||||||
|
conferenceCallCallBackButton: '#EEEFF1',
|
||||||
|
conferenceCallCallBackText: '#1F2329',
|
||||||
|
conferenceCallDisabledIcon: '#6C727A',
|
||||||
|
conferenceCallEnabledIcon: '#FFFFFF',
|
||||||
|
conferenceCallEnabledIconBackground: '#156FF5',
|
||||||
|
conferenceCallPhotoBackground: '#E4E7EA',
|
||||||
textInputSecondaryBackground: '#E4E7EA',
|
textInputSecondaryBackground: '#E4E7EA',
|
||||||
...mentions
|
...mentions
|
||||||
},
|
},
|
||||||
|
@ -123,6 +139,22 @@ export const colors = {
|
||||||
collapsibleQuoteBorder: '#CBCED1',
|
collapsibleQuoteBorder: '#CBCED1',
|
||||||
collapsibleChevron: '#6C727A',
|
collapsibleChevron: '#6C727A',
|
||||||
cancelButton: '#E4E7EA',
|
cancelButton: '#E4E7EA',
|
||||||
|
conferenceCallBorder: '#1F2329',
|
||||||
|
conferenceCallBackground: '#1F2329',
|
||||||
|
conferenceCallOngoingPhoneBackground: '#106D4F',
|
||||||
|
conferenceCallIncomingPhoneBackground: '#D1EBFE',
|
||||||
|
conferenceCallEndedPhoneBackground: '#6C727A',
|
||||||
|
conferenceCallOngoingPhoneIcon: '#F7F8FA',
|
||||||
|
conferenceCallIncomingPhoneIcon: '#095AD2',
|
||||||
|
conferenceCallEndedPhoneIcon: '#F7F8FA',
|
||||||
|
conferenceCallPlusUsersButton: '#2F343D',
|
||||||
|
conferenceCallPlusUsersText: '#9EA2A8',
|
||||||
|
conferenceCallCallBackButton: '#E4E7EA',
|
||||||
|
conferenceCallCallBackText: '#FFFFFF',
|
||||||
|
conferenceCallDisabledIcon: '#6C727A',
|
||||||
|
conferenceCallEnabledIcon: '#FFFFFF',
|
||||||
|
conferenceCallEnabledIconBackground: '#156FF5',
|
||||||
|
conferenceCallPhotoBackground: '#E4E7EA',
|
||||||
textInputSecondaryBackground: '#030b1b', // backgroundColor
|
textInputSecondaryBackground: '#030b1b', // backgroundColor
|
||||||
...mentions
|
...mentions
|
||||||
},
|
},
|
||||||
|
@ -176,6 +208,22 @@ export const colors = {
|
||||||
collapsibleQuoteBorder: '#CBCED1',
|
collapsibleQuoteBorder: '#CBCED1',
|
||||||
collapsibleChevron: '#6C727A',
|
collapsibleChevron: '#6C727A',
|
||||||
cancelButton: '#E4E7EA',
|
cancelButton: '#E4E7EA',
|
||||||
|
conferenceCallBorder: '#1F2329',
|
||||||
|
conferenceCallBackground: '#1F2329',
|
||||||
|
conferenceCallOngoingPhoneBackground: '#106D4F',
|
||||||
|
conferenceCallIncomingPhoneBackground: '#D1EBFE',
|
||||||
|
conferenceCallEndedPhoneBackground: '#6C727A',
|
||||||
|
conferenceCallOngoingPhoneIcon: '#F7F8FA',
|
||||||
|
conferenceCallIncomingPhoneIcon: '#095AD2',
|
||||||
|
conferenceCallEndedPhoneIcon: '#F7F8FA',
|
||||||
|
conferenceCallPlusUsersButton: '#2F343D',
|
||||||
|
conferenceCallPlusUsersText: '#9EA2A8',
|
||||||
|
conferenceCallCallBackButton: '#E4E7EA',
|
||||||
|
conferenceCallCallBackText: '#FFFFFF',
|
||||||
|
conferenceCallDisabledIcon: '#6C727A',
|
||||||
|
conferenceCallEnabledIcon: '#FFFFFF',
|
||||||
|
conferenceCallEnabledIconBackground: '#156FF5',
|
||||||
|
conferenceCallPhotoBackground: '#E4E7EA',
|
||||||
textInputSecondaryBackground: '#000000', // backgroundColor
|
textInputSecondaryBackground: '#000000', // backgroundColor
|
||||||
...mentions
|
...mentions
|
||||||
}
|
}
|
||||||
|
|
|
@ -123,6 +123,8 @@ export default class Subscription extends Model {
|
||||||
|
|
||||||
@field('e2e_key') E2EKey;
|
@field('e2e_key') E2EKey;
|
||||||
|
|
||||||
|
@field('e2e_suggested_key') E2ESuggestedKey;
|
||||||
|
|
||||||
@field('encrypted') encrypted;
|
@field('encrypted') encrypted;
|
||||||
|
|
||||||
@field('e2e_key_id') e2eKeyId;
|
@field('e2e_key_id') e2eKeyId;
|
||||||
|
|
|
@ -16,6 +16,8 @@ export default class Upload extends Model {
|
||||||
|
|
||||||
@field('name') name;
|
@field('name') name;
|
||||||
|
|
||||||
|
@field('tmid') tmid;
|
||||||
|
|
||||||
@field('description') description;
|
@field('description') description;
|
||||||
|
|
||||||
@field('size') size;
|
@field('size') size;
|
||||||
|
|
|
@ -239,6 +239,24 @@ export default schemaMigrations({
|
||||||
columns: [{ name: 'hide_mention_status', type: 'boolean', isOptional: true }]
|
columns: [{ name: 'hide_mention_status', type: 'boolean', isOptional: true }]
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
toVersion: 19,
|
||||||
|
steps: [
|
||||||
|
addColumns({
|
||||||
|
table: 'uploads',
|
||||||
|
columns: [{ name: 'tmid', type: 'string', isOptional: true }]
|
||||||
|
})
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
toVersion: 20,
|
||||||
|
steps: [
|
||||||
|
addColumns({
|
||||||
|
table: 'subscriptions',
|
||||||
|
columns: [{ name: 'e2e_suggested_key', type: 'string', isOptional: true }]
|
||||||
|
})
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { appSchema, tableSchema } from '@nozbe/watermelondb';
|
import { appSchema, tableSchema } from '@nozbe/watermelondb';
|
||||||
|
|
||||||
export default appSchema({
|
export default appSchema({
|
||||||
version: 18,
|
version: 20,
|
||||||
tables: [
|
tables: [
|
||||||
tableSchema({
|
tableSchema({
|
||||||
name: 'subscriptions',
|
name: 'subscriptions',
|
||||||
|
@ -55,6 +55,7 @@ export default appSchema({
|
||||||
{ name: 'livechat_data', type: 'string', isOptional: true },
|
{ name: 'livechat_data', type: 'string', isOptional: true },
|
||||||
{ name: 'tags', type: 'string', isOptional: true },
|
{ name: 'tags', type: 'string', isOptional: true },
|
||||||
{ name: 'e2e_key', type: 'string', isOptional: true },
|
{ name: 'e2e_key', type: 'string', isOptional: true },
|
||||||
|
{ name: 'e2e_suggested_key', type: 'string', isOptional: true },
|
||||||
{ name: 'encrypted', type: 'boolean', isOptional: true },
|
{ name: 'encrypted', type: 'boolean', isOptional: true },
|
||||||
{ name: 'e2e_key_id', type: 'string', isOptional: true },
|
{ name: 'e2e_key_id', type: 'string', isOptional: true },
|
||||||
{ name: 'avatar_etag', type: 'string', isOptional: true },
|
{ name: 'avatar_etag', type: 'string', isOptional: true },
|
||||||
|
@ -222,6 +223,7 @@ export default appSchema({
|
||||||
{ name: 'path', type: 'string', isOptional: true },
|
{ name: 'path', type: 'string', isOptional: true },
|
||||||
{ name: 'rid', type: 'string', isIndexed: true },
|
{ name: 'rid', type: 'string', isIndexed: true },
|
||||||
{ name: 'name', type: 'string', isOptional: true },
|
{ name: 'name', type: 'string', isOptional: true },
|
||||||
|
{ name: 'tmid', type: 'string', isOptional: true },
|
||||||
{ name: 'description', type: 'string', isOptional: true },
|
{ name: 'description', type: 'string', isOptional: true },
|
||||||
{ name: 'size', type: 'number' },
|
{ name: 'size', type: 'number' },
|
||||||
{ name: 'type', type: 'string', isOptional: true },
|
{ name: 'type', type: 'string', isOptional: true },
|
||||||
|
|
|
@ -34,6 +34,7 @@ class Encryption {
|
||||||
handshake: Function;
|
handshake: Function;
|
||||||
decrypt: Function;
|
decrypt: Function;
|
||||||
encrypt: Function;
|
encrypt: Function;
|
||||||
|
importRoomKey: Function;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,6 +98,10 @@ class Encryption {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
stopRoom = (rid: string) => {
|
||||||
|
delete this.roomInstances[rid];
|
||||||
|
};
|
||||||
|
|
||||||
// When a new participant join and request a new room encryption key
|
// When a new participant join and request a new room encryption key
|
||||||
provideRoomKeyToUser = async (keyId: string, rid: string) => {
|
provideRoomKeyToUser = async (keyId: string, rid: string) => {
|
||||||
// If the client is not ready
|
// If the client is not ready
|
||||||
|
@ -220,6 +225,19 @@ class Encryption {
|
||||||
return roomE2E;
|
return roomE2E;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
evaluateSuggestedKey = async (rid: string, E2ESuggestedKey: string) => {
|
||||||
|
try {
|
||||||
|
if (this.privateKey) {
|
||||||
|
const roomE2E = await this.getRoomInstance(rid);
|
||||||
|
await roomE2E.importRoomKey(E2ESuggestedKey, this.privateKey);
|
||||||
|
delete this.roomInstances[rid];
|
||||||
|
await Services.e2eAcceptSuggestedGroupKey(rid);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
await Services.e2eRejectSuggestedGroupKey(rid);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Logic to decrypt all pending messages/threads/threadMessages
|
// Logic to decrypt all pending messages/threads/threadMessages
|
||||||
// after initialize the encryption client
|
// after initialize the encryption client
|
||||||
decryptPendingMessages = async (roomId?: string) => {
|
decryptPendingMessages = async (roomId?: string) => {
|
||||||
|
|
|
@ -74,7 +74,10 @@ export default class EncryptionRoom {
|
||||||
if (E2EKey && Encryption.privateKey) {
|
if (E2EKey && Encryption.privateKey) {
|
||||||
// We're establishing a new room encryption client
|
// We're establishing a new room encryption client
|
||||||
this.establishing = true;
|
this.establishing = true;
|
||||||
await this.importRoomKey(E2EKey, Encryption.privateKey);
|
const { keyID, roomKey, sessionKeyExportedString } = await this.importRoomKey(E2EKey, Encryption.privateKey);
|
||||||
|
this.keyID = keyID;
|
||||||
|
this.roomKey = roomKey;
|
||||||
|
this.sessionKeyExportedString = sessionKeyExportedString;
|
||||||
this.readyPromise.resolve();
|
this.readyPromise.resolve();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -96,20 +99,33 @@ export default class EncryptionRoom {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Import roomKey as an AES Decrypt key
|
// Import roomKey as an AES Decrypt key
|
||||||
importRoomKey = async (E2EKey: string, privateKey: string) => {
|
importRoomKey = async (
|
||||||
const roomE2EKey = E2EKey.slice(12);
|
E2EKey: string,
|
||||||
|
privateKey: string
|
||||||
|
): Promise<{ sessionKeyExportedString: string | ByteBuffer; roomKey: ArrayBuffer; keyID: string }> => {
|
||||||
|
try {
|
||||||
|
const roomE2EKey = E2EKey.slice(12);
|
||||||
|
|
||||||
const decryptedKey = await SimpleCrypto.RSA.decrypt(roomE2EKey, privateKey);
|
const decryptedKey = await SimpleCrypto.RSA.decrypt(roomE2EKey, privateKey);
|
||||||
this.sessionKeyExportedString = toString(decryptedKey);
|
const sessionKeyExportedString = toString(decryptedKey);
|
||||||
|
|
||||||
this.keyID = Base64.encode(this.sessionKeyExportedString as string).slice(0, 12);
|
const keyID = Base64.encode(sessionKeyExportedString as string).slice(0, 12);
|
||||||
|
|
||||||
// Extract K from Web Crypto Secret Key
|
// Extract K from Web Crypto Secret Key
|
||||||
// K is a base64URL encoded array of bytes
|
// K is a base64URL encoded array of bytes
|
||||||
// Web Crypto API uses this as a private key to decrypt/encrypt things
|
// Web Crypto API uses this as a private key to decrypt/encrypt things
|
||||||
// Reference: https://www.javadoc.io/doc/com.nimbusds/nimbus-jose-jwt/5.1/com/nimbusds/jose/jwk/OctetSequenceKey.html
|
// Reference: https://www.javadoc.io/doc/com.nimbusds/nimbus-jose-jwt/5.1/com/nimbusds/jose/jwk/OctetSequenceKey.html
|
||||||
const { k } = EJSON.parse(this.sessionKeyExportedString as string);
|
const { k } = EJSON.parse(sessionKeyExportedString as string);
|
||||||
this.roomKey = b64ToBuffer(k);
|
const roomKey = b64ToBuffer(k);
|
||||||
|
|
||||||
|
return {
|
||||||
|
sessionKeyExportedString,
|
||||||
|
roomKey,
|
||||||
|
keyID
|
||||||
|
};
|
||||||
|
} catch (e: any) {
|
||||||
|
throw new Error(e);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Create a key to a room
|
// Create a key to a room
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { useDimensions } from '@react-native-community/hooks';
|
||||||
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
||||||
|
|
||||||
|
// Not sure if it's worth adding this here in the context of the actionSheet
|
||||||
|
/**
|
||||||
|
* Return the snaps based on the size you pass (aka: Size of action sheet)
|
||||||
|
* @param {Number[]} snaps Sizes you want to pass, pass only one if you want the action sheet to start at a specific size
|
||||||
|
*/
|
||||||
|
export const useSnaps = (snaps: number[]): string[] => {
|
||||||
|
const insets = useSafeAreaInsets();
|
||||||
|
const { screen } = useDimensions();
|
||||||
|
const percentage = insets.bottom + insets.top > 75 ? 110 : 100;
|
||||||
|
return snaps.map(snap => `${((percentage * snap) / (screen.height * screen.scale)).toFixed(2)}%`);
|
||||||
|
};
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
|
import { TActionSheetOptionsItem, useActionSheet } from '../../containers/ActionSheet';
|
||||||
|
import i18n from '../../i18n';
|
||||||
|
import { videoConfJoin } from '../methods/videoConf';
|
||||||
|
|
||||||
|
export const useVideoConf = (): { joinCall: (blockId: string) => void } => {
|
||||||
|
const { showActionSheet } = useActionSheet();
|
||||||
|
|
||||||
|
const joinCall = useCallback(blockId => {
|
||||||
|
const options: TActionSheetOptionsItem[] = [
|
||||||
|
{
|
||||||
|
title: i18n.t('Video_call'),
|
||||||
|
icon: 'camera',
|
||||||
|
onPress: () => videoConfJoin(blockId, true)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: i18n.t('Voice_call'),
|
||||||
|
icon: 'microphone',
|
||||||
|
onPress: () => videoConfJoin(blockId, false)
|
||||||
|
}
|
||||||
|
];
|
||||||
|
showActionSheet({ options });
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return { joinCall };
|
||||||
|
};
|
|
@ -4,12 +4,17 @@ import { sanitizeLikeString } from '../database/utils';
|
||||||
import { store } from '../store/auxStore';
|
import { store } from '../store/auxStore';
|
||||||
import log from './helpers/log';
|
import log from './helpers/log';
|
||||||
|
|
||||||
|
const DEFAULT_EXTENSION = 'mp3';
|
||||||
|
|
||||||
const sanitizeString = (value: string) => sanitizeLikeString(value.substring(value.lastIndexOf('/') + 1));
|
const sanitizeString = (value: string) => sanitizeLikeString(value.substring(value.lastIndexOf('/') + 1));
|
||||||
|
|
||||||
const parseFilename = (value: string) => {
|
const getExtension = (value: string) => {
|
||||||
const extension = value.substring(value.lastIndexOf('.') + 1);
|
let extension = DEFAULT_EXTENSION;
|
||||||
const filename = sanitizeString(value.substring(value.lastIndexOf('/') + 1).split('.')[0]);
|
const filename = value.split('/').pop();
|
||||||
return `${filename}.${extension}`;
|
if (filename?.includes('.')) {
|
||||||
|
extension = value.substring(value.lastIndexOf('.') + 1);
|
||||||
|
}
|
||||||
|
return extension;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ensureDirAsync = async (dir: string, intermediates = true): Promise<void> => {
|
const ensureDirAsync = async (dir: string, intermediates = true): Promise<void> => {
|
||||||
|
@ -27,7 +32,7 @@ export const downloadAudioFile = async (url: string, fileUrl: string, messageId:
|
||||||
const serverUrl = store.getState().server.server;
|
const serverUrl = store.getState().server.server;
|
||||||
const serverUrlParsed = sanitizeString(serverUrl);
|
const serverUrlParsed = sanitizeString(serverUrl);
|
||||||
const folderPath = `${FileSystem.documentDirectory}audios/${serverUrlParsed}`;
|
const folderPath = `${FileSystem.documentDirectory}audios/${serverUrlParsed}`;
|
||||||
const filename = `${messageId}_${parseFilename(fileUrl)}`;
|
const filename = `${messageId}.${getExtension(fileUrl)}`;
|
||||||
const filePath = `${folderPath}/${filename}`;
|
const filePath = `${folderPath}/${filename}`;
|
||||||
await ensureDirAsync(folderPath);
|
await ensureDirAsync(folderPath);
|
||||||
const file = await FileSystem.getInfoAsync(filePath);
|
const file = await FileSystem.getInfoAsync(filePath);
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
import { SubscriptionType, TAnyMessageModel } from '../../../definitions';
|
import { SubscriptionType, TAnyMessageModel } from '../../definitions';
|
||||||
import { loadNextMessages, loadMessagesForRoom } from '../../../lib/methods';
|
import { loadNextMessages, loadMessagesForRoom } from '.';
|
||||||
import { MessageTypeLoad } from '../../../lib/constants';
|
import { MessageTypeLoad } from '../constants';
|
||||||
|
|
||||||
const getMoreMessages = ({
|
const getMoreMessages = ({
|
||||||
rid,
|
rid,
|
||||||
t,
|
t,
|
||||||
tmid,
|
|
||||||
loaderItem
|
loaderItem
|
||||||
}: {
|
}: {
|
||||||
rid: string;
|
rid: string;
|
||||||
t: SubscriptionType;
|
t: SubscriptionType;
|
||||||
tmid?: string;
|
|
||||||
loaderItem: TAnyMessageModel;
|
loaderItem: TAnyMessageModel;
|
||||||
}): Promise<void> => {
|
}): Promise<void> => {
|
||||||
if ([MessageTypeLoad.MORE, MessageTypeLoad.PREVIOUS_CHUNK].includes(loaderItem.t as MessageTypeLoad)) {
|
if ([MessageTypeLoad.MORE, MessageTypeLoad.PREVIOUS_CHUNK].includes(loaderItem.t as MessageTypeLoad)) {
|
||||||
|
@ -25,7 +23,6 @@ const getMoreMessages = ({
|
||||||
if (loaderItem.t === MessageTypeLoad.NEXT_CHUNK) {
|
if (loaderItem.t === MessageTypeLoad.NEXT_CHUNK) {
|
||||||
return loadNextMessages({
|
return loadNextMessages({
|
||||||
rid,
|
rid,
|
||||||
tmid,
|
|
||||||
ts: loaderItem.ts as Date,
|
ts: loaderItem.ts as Date,
|
||||||
loaderItem
|
loaderItem
|
||||||
});
|
});
|
|
@ -57,7 +57,8 @@ export const SUPPORTED_PERMISSIONS = [
|
||||||
'edit-omnichannel-contact',
|
'edit-omnichannel-contact',
|
||||||
'edit-livechat-room-customfields',
|
'edit-livechat-room-customfields',
|
||||||
'view-canned-responses',
|
'view-canned-responses',
|
||||||
'mobile-upload-file'
|
'mobile-upload-file',
|
||||||
|
'delete-own-message'
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
export async function setPermissions(): Promise<void> {
|
export async function setPermissions(): Promise<void> {
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import { ChatsStackParamList } from '../../../stacks/types';
|
import { CommonActions } from '@react-navigation/native';
|
||||||
|
|
||||||
import Navigation from '../../navigation/appNavigation';
|
import Navigation from '../../navigation/appNavigation';
|
||||||
import { IOmnichannelRoom, SubscriptionType, IVisitor, TSubscriptionModel, ISubscription } from '../../../definitions';
|
import { IOmnichannelRoom, SubscriptionType, IVisitor, TSubscriptionModel, ISubscription } from '../../../definitions';
|
||||||
import { getRoomTitle, getUidDirectMessage } from './helpers';
|
import { getRoomTitle, getUidDirectMessage } from './helpers';
|
||||||
|
@ -19,19 +20,14 @@ export type TGoRoomItem = IGoRoomItem | TSubscriptionModel | ISubscription | IOm
|
||||||
const navigate = ({
|
const navigate = ({
|
||||||
item,
|
item,
|
||||||
isMasterDetail,
|
isMasterDetail,
|
||||||
|
popToRoot,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
item: TGoRoomItem;
|
item: TGoRoomItem;
|
||||||
isMasterDetail: boolean;
|
isMasterDetail: boolean;
|
||||||
navigationMethod?: () => ChatsStackParamList;
|
popToRoot: boolean;
|
||||||
}) => {
|
}) => {
|
||||||
let navigationMethod = props.navigationMethod ?? Navigation.navigate;
|
const routeParams = {
|
||||||
|
|
||||||
if (isMasterDetail) {
|
|
||||||
navigationMethod = Navigation.replace;
|
|
||||||
}
|
|
||||||
|
|
||||||
navigationMethod('RoomView', {
|
|
||||||
rid: item.rid,
|
rid: item.rid,
|
||||||
name: getRoomTitle(item),
|
name: getRoomTitle(item),
|
||||||
t: item.t,
|
t: item.t,
|
||||||
|
@ -40,6 +36,44 @@ const navigate = ({
|
||||||
visitor: item.visitor,
|
visitor: item.visitor,
|
||||||
roomUserId: getUidDirectMessage(item),
|
roomUserId: getUidDirectMessage(item),
|
||||||
...props
|
...props
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isMasterDetail) {
|
||||||
|
if (popToRoot) {
|
||||||
|
Navigation.navigate('DrawerNavigator');
|
||||||
|
}
|
||||||
|
return Navigation.dispatch((state: any) => {
|
||||||
|
const routesRoomView = state.routes.filter((r: any) => r.name !== 'RoomView');
|
||||||
|
return CommonActions.reset({
|
||||||
|
...state,
|
||||||
|
routes: [
|
||||||
|
...routesRoomView,
|
||||||
|
{
|
||||||
|
name: 'RoomView',
|
||||||
|
params: routeParams
|
||||||
|
}
|
||||||
|
],
|
||||||
|
index: routesRoomView.length
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (popToRoot) {
|
||||||
|
Navigation.navigate('RoomsListView');
|
||||||
|
}
|
||||||
|
return Navigation.dispatch((state: any) => {
|
||||||
|
const routesRoomsListView = state.routes.filter((r: any) => r.name === 'RoomsListView');
|
||||||
|
return CommonActions.reset({
|
||||||
|
...state,
|
||||||
|
routes: [
|
||||||
|
...routesRoomsListView,
|
||||||
|
{
|
||||||
|
name: 'RoomView',
|
||||||
|
params: routeParams
|
||||||
|
}
|
||||||
|
],
|
||||||
|
index: routesRoomsListView.length
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,13 +85,14 @@ interface IOmnichannelRoomVisitor extends IOmnichannelRoom {
|
||||||
export const goRoom = async ({
|
export const goRoom = async ({
|
||||||
item,
|
item,
|
||||||
isMasterDetail = false,
|
isMasterDetail = false,
|
||||||
|
popToRoot = false,
|
||||||
...props
|
...props
|
||||||
}: {
|
}: {
|
||||||
item: TGoRoomItem;
|
item: TGoRoomItem;
|
||||||
isMasterDetail: boolean;
|
isMasterDetail: boolean;
|
||||||
navigationMethod?: any;
|
|
||||||
jumpToMessageId?: string;
|
jumpToMessageId?: string;
|
||||||
usedCannedResponse?: string;
|
usedCannedResponse?: string;
|
||||||
|
popToRoot?: boolean;
|
||||||
}): Promise<void> => {
|
}): Promise<void> => {
|
||||||
if (!('id' in item) && item.t === SubscriptionType.DIRECT && item?.search) {
|
if (!('id' in item) && item.t === SubscriptionType.DIRECT && item?.search) {
|
||||||
// if user is using the search we need first to join/create room
|
// if user is using the search we need first to join/create room
|
||||||
|
@ -72,6 +107,7 @@ export const goRoom = async ({
|
||||||
t: SubscriptionType.DIRECT
|
t: SubscriptionType.DIRECT
|
||||||
},
|
},
|
||||||
isMasterDetail,
|
isMasterDetail,
|
||||||
|
popToRoot,
|
||||||
...props
|
...props
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -80,5 +116,5 @@ export const goRoom = async ({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return navigate({ item, isMasterDetail, ...props });
|
return navigate({ item, isMasterDetail, popToRoot, ...props });
|
||||||
};
|
};
|
||||||
|
|
|
@ -10,6 +10,7 @@ export * from './animations';
|
||||||
|
|
||||||
export const defaultHeader = {
|
export const defaultHeader = {
|
||||||
headerBackTitleVisible: false,
|
headerBackTitleVisible: false,
|
||||||
|
headerBackTestID: 'header-back',
|
||||||
cardOverlayEnabled: true,
|
cardOverlayEnabled: true,
|
||||||
cardStyle: { backgroundColor: 'transparent' }
|
cardStyle: { backgroundColor: 'transparent' }
|
||||||
};
|
};
|
||||||
|
|
|
@ -33,6 +33,9 @@ const RCSSLPinning = Platform.select({
|
||||||
type: ['com.rsa.pkcs-12']
|
type: ['com.rsa.pkcs-12']
|
||||||
});
|
});
|
||||||
const { uri, name } = res;
|
const { uri, name } = res;
|
||||||
|
if (!name) {
|
||||||
|
return reject();
|
||||||
|
}
|
||||||
Alert.prompt(
|
Alert.prompt(
|
||||||
I18n.t('Certificate_password'),
|
I18n.t('Certificate_password'),
|
||||||
I18n.t('Whats_the_password_for_your_certificate'),
|
I18n.t('Whats_the_password_for_your_certificate'),
|
||||||
|
|
|
@ -16,6 +16,7 @@ export * from './getSingleMessage';
|
||||||
export * from './getSlashCommands';
|
export * from './getSlashCommands';
|
||||||
export * from './getThreadName';
|
export * from './getThreadName';
|
||||||
export * from './getUsersPresence';
|
export * from './getUsersPresence';
|
||||||
|
export * from './getMoreMessages';
|
||||||
export * from './loadMessagesForRoom';
|
export * from './loadMessagesForRoom';
|
||||||
export * from './loadMissedMessages';
|
export * from './loadMissedMessages';
|
||||||
export * from './loadNextMessages';
|
export * from './loadNextMessages';
|
||||||
|
|
|
@ -15,7 +15,6 @@ const COUNT = 50;
|
||||||
interface ILoadNextMessages {
|
interface ILoadNextMessages {
|
||||||
rid: string;
|
rid: string;
|
||||||
ts: Date;
|
ts: Date;
|
||||||
tmid?: string;
|
|
||||||
loaderItem: TMessageModel;
|
loaderItem: TMessageModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +31,6 @@ export function loadNextMessages(args: ILoadNextMessages): Promise<void> {
|
||||||
const loadMoreItem = {
|
const loadMoreItem = {
|
||||||
_id: generateLoadMoreId(lastMessage._id),
|
_id: generateLoadMoreId(lastMessage._id),
|
||||||
rid: lastMessage.rid,
|
rid: lastMessage.rid,
|
||||||
tmid: args.tmid,
|
|
||||||
ts: moment(lastMessage.ts).add(1, 'millisecond'),
|
ts: moment(lastMessage.ts).add(1, 'millisecond'),
|
||||||
t: MessageTypeLoad.NEXT_CHUNK
|
t: MessageTypeLoad.NEXT_CHUNK
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,9 +19,6 @@ export function loadSurroundingMessages({ messageId, rid }: { messageId: string;
|
||||||
let messages: IMessage[] = EJSON.fromJSONValue(data?.messages);
|
let messages: IMessage[] = EJSON.fromJSONValue(data?.messages);
|
||||||
messages = orderBy(messages, 'ts');
|
messages = orderBy(messages, 'ts');
|
||||||
|
|
||||||
const message = messages.find(m => m._id === messageId);
|
|
||||||
const tmid = message?.tmid;
|
|
||||||
|
|
||||||
if (messages?.length) {
|
if (messages?.length) {
|
||||||
if (data?.moreBefore) {
|
if (data?.moreBefore) {
|
||||||
const firstMessage = messages[0];
|
const firstMessage = messages[0];
|
||||||
|
@ -30,7 +27,6 @@ export function loadSurroundingMessages({ messageId, rid }: { messageId: string;
|
||||||
const loadMoreItem = {
|
const loadMoreItem = {
|
||||||
_id: generateLoadMoreId(firstMessage._id),
|
_id: generateLoadMoreId(firstMessage._id),
|
||||||
rid: firstMessage.rid,
|
rid: firstMessage.rid,
|
||||||
tmid,
|
|
||||||
ts: moment(firstMessage.ts).subtract(1, 'millisecond').toDate(),
|
ts: moment(firstMessage.ts).subtract(1, 'millisecond').toDate(),
|
||||||
t: MessageTypeLoad.PREVIOUS_CHUNK,
|
t: MessageTypeLoad.PREVIOUS_CHUNK,
|
||||||
msg: firstMessage.msg
|
msg: firstMessage.msg
|
||||||
|
@ -46,7 +42,6 @@ export function loadSurroundingMessages({ messageId, rid }: { messageId: string;
|
||||||
const loadMoreItem = {
|
const loadMoreItem = {
|
||||||
_id: generateLoadMoreId(lastMessage._id),
|
_id: generateLoadMoreId(lastMessage._id),
|
||||||
rid: lastMessage.rid,
|
rid: lastMessage.rid,
|
||||||
tmid,
|
|
||||||
ts: moment(lastMessage.ts).add(1, 'millisecond').toDate(),
|
ts: moment(lastMessage.ts).add(1, 'millisecond').toDate(),
|
||||||
t: MessageTypeLoad.NEXT_CHUNK,
|
t: MessageTypeLoad.NEXT_CHUNK,
|
||||||
msg: lastMessage.msg
|
msg: lastMessage.msg
|
||||||
|
|
|
@ -38,7 +38,8 @@ export const localSearchSubscription = async ({ text = '', filterUsers = true, f
|
||||||
t: item.t,
|
t: item.t,
|
||||||
encrypted: item.encrypted,
|
encrypted: item.encrypted,
|
||||||
lastMessage: item.lastMessage,
|
lastMessage: item.lastMessage,
|
||||||
status: item.status
|
status: item.status,
|
||||||
|
teamMain: item.teamMain
|
||||||
})) as ISearchLocal[];
|
})) as ISearchLocal[];
|
||||||
|
|
||||||
return search;
|
return search;
|
||||||
|
|
|
@ -1,27 +1,35 @@
|
||||||
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord';
|
||||||
import { settings as RocketChatSettings } from '@rocket.chat/sdk';
|
import { settings as RocketChatSettings } from '@rocket.chat/sdk';
|
||||||
import { FetchBlobResponse, StatefulPromise } from 'rn-fetch-blob';
|
|
||||||
import isEmpty from 'lodash/isEmpty';
|
import isEmpty from 'lodash/isEmpty';
|
||||||
|
import { FetchBlobResponse, StatefulPromise } from 'rn-fetch-blob';
|
||||||
|
import { Alert } from 'react-native';
|
||||||
|
|
||||||
import FileUpload from './helpers/fileUpload';
|
|
||||||
import database from '../database';
|
|
||||||
import log from './helpers/log';
|
|
||||||
import { IUpload, IUser, TUploadModel } from '../../definitions';
|
import { IUpload, IUser, TUploadModel } from '../../definitions';
|
||||||
|
import i18n from '../../i18n';
|
||||||
|
import database from '../database';
|
||||||
|
import FileUpload from './helpers/fileUpload';
|
||||||
import { IFileUpload } from './helpers/fileUpload/interfaces';
|
import { IFileUpload } from './helpers/fileUpload/interfaces';
|
||||||
|
import log from './helpers/log';
|
||||||
|
|
||||||
const uploadQueue: { [index: string]: StatefulPromise<FetchBlobResponse> } = {};
|
const uploadQueue: { [index: string]: StatefulPromise<FetchBlobResponse> } = {};
|
||||||
|
|
||||||
export function isUploadActive(path: string): boolean {
|
const getUploadPath = (path: string, rid: string) => `${path}-${rid}`;
|
||||||
return !!uploadQueue[path];
|
|
||||||
|
export function isUploadActive(path: string, rid: string): boolean {
|
||||||
|
return !!uploadQueue[getUploadPath(path, rid)];
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function cancelUpload(item: TUploadModel): Promise<void> {
|
export async function cancelUpload(item: TUploadModel, rid: string): Promise<void> {
|
||||||
if (!isEmpty(uploadQueue[item.path])) {
|
const uploadPath = getUploadPath(item.path, rid);
|
||||||
|
if (!isEmpty(uploadQueue[uploadPath])) {
|
||||||
try {
|
try {
|
||||||
await uploadQueue[item.path].cancel();
|
await uploadQueue[uploadPath].cancel();
|
||||||
} catch {
|
} catch {
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
delete uploadQueue[uploadPath];
|
||||||
|
}
|
||||||
|
if (item.id) {
|
||||||
try {
|
try {
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
await db.write(async () => {
|
await db.write(async () => {
|
||||||
|
@ -30,7 +38,6 @@ export async function cancelUpload(item: TUploadModel): Promise<void> {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(e);
|
log(e);
|
||||||
}
|
}
|
||||||
delete uploadQueue[item.path];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +46,8 @@ export function sendFileMessage(
|
||||||
fileInfo: IUpload,
|
fileInfo: IUpload,
|
||||||
tmid: string | undefined,
|
tmid: string | undefined,
|
||||||
server: string,
|
server: string,
|
||||||
user: Partial<Pick<IUser, 'id' | 'token'>>
|
user: Partial<Pick<IUser, 'id' | 'token'>>,
|
||||||
|
isForceTryAgain?: boolean
|
||||||
): Promise<FetchBlobResponse | void> {
|
): Promise<FetchBlobResponse | void> {
|
||||||
return new Promise(async (resolve, reject) => {
|
return new Promise(async (resolve, reject) => {
|
||||||
try {
|
try {
|
||||||
|
@ -51,15 +59,22 @@ export function sendFileMessage(
|
||||||
|
|
||||||
const db = database.active;
|
const db = database.active;
|
||||||
const uploadsCollection = db.get('uploads');
|
const uploadsCollection = db.get('uploads');
|
||||||
|
const uploadPath = getUploadPath(fileInfo.path, rid);
|
||||||
let uploadRecord: TUploadModel;
|
let uploadRecord: TUploadModel;
|
||||||
try {
|
try {
|
||||||
uploadRecord = await uploadsCollection.find(fileInfo.path);
|
uploadRecord = await uploadsCollection.find(uploadPath);
|
||||||
|
if (uploadRecord.id && !isForceTryAgain) {
|
||||||
|
return Alert.alert(i18n.t('FileUpload_Error'), i18n.t('Upload_in_progress'));
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
try {
|
try {
|
||||||
await db.write(async () => {
|
await db.write(async () => {
|
||||||
uploadRecord = await uploadsCollection.create(u => {
|
uploadRecord = await uploadsCollection.create(u => {
|
||||||
u._raw = sanitizedRaw({ id: fileInfo.path }, uploadsCollection.schema);
|
u._raw = sanitizedRaw({ id: uploadPath }, uploadsCollection.schema);
|
||||||
Object.assign(u, fileInfo);
|
Object.assign(u, fileInfo);
|
||||||
|
if (tmid) {
|
||||||
|
u.tmid = tmid;
|
||||||
|
}
|
||||||
if (u.subscription) {
|
if (u.subscription) {
|
||||||
u.subscription.id = rid;
|
u.subscription.id = rid;
|
||||||
}
|
}
|
||||||
|
@ -85,6 +100,13 @@ export function sendFileMessage(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fileInfo.msg) {
|
||||||
|
formData.push({
|
||||||
|
name: 'msg',
|
||||||
|
data: fileInfo.msg
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (tmid) {
|
if (tmid) {
|
||||||
formData.push({
|
formData.push({
|
||||||
name: 'tmid',
|
name: 'tmid',
|
||||||
|
@ -99,9 +121,9 @@ export function sendFileMessage(
|
||||||
'X-User-Id': id
|
'X-User-Id': id
|
||||||
};
|
};
|
||||||
|
|
||||||
uploadQueue[fileInfo.path] = FileUpload.fetch('POST', uploadUrl, headers, formData);
|
uploadQueue[uploadPath] = FileUpload.fetch('POST', uploadUrl, headers, formData);
|
||||||
|
|
||||||
uploadQueue[fileInfo.path].uploadProgress(async (loaded: number, total: number) => {
|
uploadQueue[uploadPath].uploadProgress(async (loaded: number, total: number) => {
|
||||||
try {
|
try {
|
||||||
await db.write(async () => {
|
await db.write(async () => {
|
||||||
await uploadRecord.update(u => {
|
await uploadRecord.update(u => {
|
||||||
|
@ -113,7 +135,7 @@ export function sendFileMessage(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
uploadQueue[fileInfo.path].then(async response => {
|
uploadQueue[uploadPath].then(async response => {
|
||||||
if (response.respInfo.status >= 200 && response.respInfo.status < 400) {
|
if (response.respInfo.status >= 200 && response.respInfo.status < 400) {
|
||||||
// If response is all good...
|
// If response is all good...
|
||||||
try {
|
try {
|
||||||
|
@ -142,7 +164,7 @@ export function sendFileMessage(
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
uploadQueue[fileInfo.path].catch(async error => {
|
uploadQueue[uploadPath].catch(async error => {
|
||||||
try {
|
try {
|
||||||
await db.write(async () => {
|
await db.write(async () => {
|
||||||
await uploadRecord.update(u => {
|
await uploadRecord.update(u => {
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue