[NEW] Invite links (#1534)
This commit is contained in:
parent
ba27c580f4
commit
0673081465
|
@ -54,3 +54,11 @@ export const TOGGLE_CRASH_REPORT = 'TOGGLE_CRASH_REPORT';
|
||||||
export const SET_CUSTOM_EMOJIS = 'SET_CUSTOM_EMOJIS';
|
export const SET_CUSTOM_EMOJIS = 'SET_CUSTOM_EMOJIS';
|
||||||
export const SET_ACTIVE_USERS = 'SET_ACTIVE_USERS';
|
export const SET_ACTIVE_USERS = 'SET_ACTIVE_USERS';
|
||||||
export const USERS_TYPING = createRequestTypes('USERS_TYPING', ['ADD', 'REMOVE', 'CLEAR']);
|
export const USERS_TYPING = createRequestTypes('USERS_TYPING', ['ADD', 'REMOVE', 'CLEAR']);
|
||||||
|
export const INVITE_LINKS = createRequestTypes('INVITE_LINKS', [
|
||||||
|
'SET_TOKEN',
|
||||||
|
'SET_PARAMS',
|
||||||
|
'SET_INVITE',
|
||||||
|
'CREATE',
|
||||||
|
'CLEAR',
|
||||||
|
...defaultTypes
|
||||||
|
]);
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
import * as types from './actionsTypes';
|
||||||
|
|
||||||
|
export function inviteLinksSetToken(token) {
|
||||||
|
return {
|
||||||
|
type: types.INVITE_LINKS.SET_TOKEN,
|
||||||
|
token
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function inviteLinksRequest(token) {
|
||||||
|
return {
|
||||||
|
type: types.INVITE_LINKS.REQUEST,
|
||||||
|
token
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function inviteLinksSuccess() {
|
||||||
|
return {
|
||||||
|
type: types.INVITE_LINKS.SUCCESS
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function inviteLinksFailure() {
|
||||||
|
return {
|
||||||
|
type: types.INVITE_LINKS.FAILURE
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function inviteLinksClear() {
|
||||||
|
return {
|
||||||
|
type: types.INVITE_LINKS.CLEAR
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function inviteLinksCreate(rid) {
|
||||||
|
return {
|
||||||
|
type: types.INVITE_LINKS.CREATE,
|
||||||
|
rid
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function inviteLinksSetParams(params) {
|
||||||
|
return {
|
||||||
|
type: types.INVITE_LINKS.SET_PARAMS,
|
||||||
|
params
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function inviteLinksSetInvite(invite) {
|
||||||
|
return {
|
||||||
|
type: types.INVITE_LINKS.SET_INVITE,
|
||||||
|
invite
|
||||||
|
};
|
||||||
|
}
|
|
@ -59,6 +59,9 @@ export default {
|
||||||
Message_TimeFormat: {
|
Message_TimeFormat: {
|
||||||
type: 'valueAsString'
|
type: 'valueAsString'
|
||||||
},
|
},
|
||||||
|
Message_TimeAndDateFormat: {
|
||||||
|
type: 'valueAsString'
|
||||||
|
},
|
||||||
Site_Name: {
|
Site_Name: {
|
||||||
type: 'valueAsString'
|
type: 'valueAsString'
|
||||||
},
|
},
|
||||||
|
|
|
@ -80,7 +80,7 @@ export default {
|
||||||
Activity: 'Aktivität',
|
Activity: 'Aktivität',
|
||||||
Add_Reaction: 'Reaktion hinzufügen',
|
Add_Reaction: 'Reaktion hinzufügen',
|
||||||
Add_Server: 'Server hinzufügen',
|
Add_Server: 'Server hinzufügen',
|
||||||
Add_user: 'Nutzer hinzufügen',
|
Add_users: 'Nutzer hinzufügen',
|
||||||
Admin_Panel: 'Admin Panel',
|
Admin_Panel: 'Admin Panel',
|
||||||
Alert: 'Warnen',
|
Alert: 'Warnen',
|
||||||
alert: 'warnen',
|
alert: 'warnen',
|
||||||
|
|
|
@ -81,7 +81,7 @@ export default {
|
||||||
Activity: 'Activity',
|
Activity: 'Activity',
|
||||||
Add_Reaction: 'Add Reaction',
|
Add_Reaction: 'Add Reaction',
|
||||||
Add_Server: 'Add Server',
|
Add_Server: 'Add Server',
|
||||||
Add_user: 'Add user',
|
Add_users: 'Add users',
|
||||||
Admin_Panel: 'Admin Panel',
|
Admin_Panel: 'Admin Panel',
|
||||||
Alert: 'Alert',
|
Alert: 'Alert',
|
||||||
alert: 'alert',
|
alert: 'alert',
|
||||||
|
@ -121,6 +121,7 @@ export default {
|
||||||
Cancel: 'Cancel',
|
Cancel: 'Cancel',
|
||||||
changing_avatar: 'changing avatar',
|
changing_avatar: 'changing avatar',
|
||||||
creating_channel: 'creating channel',
|
creating_channel: 'creating channel',
|
||||||
|
creating_invite: 'creating invite',
|
||||||
Channel_Name: 'Channel Name',
|
Channel_Name: 'Channel Name',
|
||||||
Channels: 'Channels',
|
Channels: 'Channels',
|
||||||
Chats: 'Chats',
|
Chats: 'Chats',
|
||||||
|
@ -172,6 +173,7 @@ export default {
|
||||||
edit: 'edit',
|
edit: 'edit',
|
||||||
edited: 'edited',
|
edited: 'edited',
|
||||||
Edit: 'Edit',
|
Edit: 'Edit',
|
||||||
|
Edit_Invite: 'Edit Invite',
|
||||||
Email_or_password_field_is_empty: 'Email or password field is empty',
|
Email_or_password_field_is_empty: 'Email or password field is empty',
|
||||||
Email: 'Email',
|
Email: 'Email',
|
||||||
EMAIL: 'EMAIL',
|
EMAIL: 'EMAIL',
|
||||||
|
@ -182,6 +184,7 @@ export default {
|
||||||
Everyone_can_access_this_channel: 'Everyone can access this channel',
|
Everyone_can_access_this_channel: 'Everyone can access this channel',
|
||||||
erasing_room: 'erasing room',
|
erasing_room: 'erasing room',
|
||||||
Error_uploading: 'Error uploading',
|
Error_uploading: 'Error uploading',
|
||||||
|
Expiration_Days: 'Expiration (Days)',
|
||||||
Favorite: 'Favorite',
|
Favorite: 'Favorite',
|
||||||
Favorites: 'Favorites',
|
Favorites: 'Favorites',
|
||||||
Files: 'Files',
|
Files: 'Files',
|
||||||
|
@ -195,6 +198,7 @@ export default {
|
||||||
Forgot_password: 'Forgot password',
|
Forgot_password: 'Forgot password',
|
||||||
Forgot_Password: 'Forgot Password',
|
Forgot_Password: 'Forgot Password',
|
||||||
Full_table: 'Click to see full table',
|
Full_table: 'Click to see full table',
|
||||||
|
Generate_New_Link: 'Generate New Link',
|
||||||
Group_by_favorites: 'Group favorites',
|
Group_by_favorites: 'Group favorites',
|
||||||
Group_by_type: 'Group by type',
|
Group_by_type: 'Group by type',
|
||||||
Hide: 'Hide',
|
Hide: 'Hide',
|
||||||
|
@ -208,7 +212,10 @@ export default {
|
||||||
is_a_valid_RocketChat_instance: 'is a valid Rocket.Chat instance',
|
is_a_valid_RocketChat_instance: 'is a valid Rocket.Chat instance',
|
||||||
is_not_a_valid_RocketChat_instance: 'is not a valid Rocket.Chat instance',
|
is_not_a_valid_RocketChat_instance: 'is not a valid Rocket.Chat instance',
|
||||||
is_typing: 'is typing',
|
is_typing: 'is typing',
|
||||||
|
Invalid_or_expired_invite_token: 'Invalid or expired invite token',
|
||||||
Invalid_server_version: 'The server you\'re trying to connect is using a version that\'s not supported by the app anymore: {{currentVersion}}.\n\nWe require version {{minVersion}}',
|
Invalid_server_version: 'The server you\'re trying to connect is using a version that\'s not supported by the app anymore: {{currentVersion}}.\n\nWe require version {{minVersion}}',
|
||||||
|
Invite_Link: 'Invite Link',
|
||||||
|
Invite_users: 'Invite users',
|
||||||
Join_the_community: 'Join the community',
|
Join_the_community: 'Join the community',
|
||||||
Join: 'Join',
|
Join: 'Join',
|
||||||
Just_invited_people_can_access_this_channel: 'Just invited people can access this channel',
|
Just_invited_people_can_access_this_channel: 'Just invited people can access this channel',
|
||||||
|
@ -225,6 +232,7 @@ export default {
|
||||||
Login_error: 'Your credentials were rejected! Please try again.',
|
Login_error: 'Your credentials were rejected! Please try again.',
|
||||||
Login_with: 'Login with',
|
Login_with: 'Login with',
|
||||||
Logout: 'Logout',
|
Logout: 'Logout',
|
||||||
|
Max_number_of_uses: 'Max number of uses',
|
||||||
members: 'members',
|
members: 'members',
|
||||||
Members: 'Members',
|
Members: 'Members',
|
||||||
Mentioned_Messages: 'Mentioned Messages',
|
Mentioned_Messages: 'Mentioned Messages',
|
||||||
|
@ -247,11 +255,13 @@ export default {
|
||||||
N_users: '{{n}} users',
|
N_users: '{{n}} users',
|
||||||
name: 'name',
|
name: 'name',
|
||||||
Name: 'Name',
|
Name: 'Name',
|
||||||
|
Never: 'Never',
|
||||||
New_Message: 'New Message',
|
New_Message: 'New Message',
|
||||||
New_Password: 'New Password',
|
New_Password: 'New Password',
|
||||||
New_Server: 'New Server',
|
New_Server: 'New Server',
|
||||||
Next: 'Next',
|
Next: 'Next',
|
||||||
No_files: 'No files',
|
No_files: 'No files',
|
||||||
|
No_limit: 'No limit',
|
||||||
No_mentioned_messages: 'No mentioned messages',
|
No_mentioned_messages: 'No mentioned messages',
|
||||||
No_pinned_messages: 'No pinned messages',
|
No_pinned_messages: 'No pinned messages',
|
||||||
No_results_found: 'No results found',
|
No_results_found: 'No results found',
|
||||||
|
@ -362,6 +372,7 @@ export default {
|
||||||
Settings: 'Settings',
|
Settings: 'Settings',
|
||||||
Settings_succesfully_changed: 'Settings succesfully changed!',
|
Settings_succesfully_changed: 'Settings succesfully changed!',
|
||||||
Share: 'Share',
|
Share: 'Share',
|
||||||
|
Share_Link: 'Share Link',
|
||||||
Share_this_app: 'Share this app',
|
Share_this_app: 'Share this app',
|
||||||
Show_Unread_Counter: 'Show Unread Counter',
|
Show_Unread_Counter: 'Show Unread Counter',
|
||||||
Show_Unread_Counter_Info: 'Unread counter is displayed as a badge on the right of the channel, in the list',
|
Show_Unread_Counter_Info: 'Unread counter is displayed as a badge on the right of the channel, in the list',
|
||||||
|
@ -449,6 +460,10 @@ export default {
|
||||||
You: 'You',
|
You: 'You',
|
||||||
You_need_to_access_at_least_one_RocketChat_server_to_share_something: 'You need to access at least one Rocket.Chat server to share something.',
|
You_need_to_access_at_least_one_RocketChat_server_to_share_something: 'You need to access at least one Rocket.Chat server to share something.',
|
||||||
Your_certificate: 'Your Certificate',
|
Your_certificate: 'Your Certificate',
|
||||||
|
Your_invite_link_will_expire_after__usesLeft__uses: 'Your invite link will expire after {{usesLeft}} uses.',
|
||||||
|
Your_invite_link_will_expire_on__date__or_after__usesLeft__uses: 'Your invite link will expire on {{date}} or after {{usesLeft}} uses.',
|
||||||
|
Your_invite_link_will_expire_on__date__: 'Your invite link will expire on {{date}}.',
|
||||||
|
Your_invite_link_will_never_expire: 'Your invite link will never expire.',
|
||||||
Version_no: 'Version: {{version}}',
|
Version_no: 'Version: {{version}}',
|
||||||
You_will_not_be_able_to_recover_this_message: 'You will not be able to recover this message!',
|
You_will_not_be_able_to_recover_this_message: 'You will not be able to recover this message!',
|
||||||
Change_Language: 'Change Language',
|
Change_Language: 'Change Language',
|
||||||
|
|
|
@ -80,7 +80,7 @@ export default {
|
||||||
Activity: 'Activité',
|
Activity: 'Activité',
|
||||||
Add_Reaction: 'Ajouter une réaction',
|
Add_Reaction: 'Ajouter une réaction',
|
||||||
Add_Server: 'Ajouter un serveur',
|
Add_Server: 'Ajouter un serveur',
|
||||||
Add_user: 'Ajouter un utilisateur',
|
Add_users: 'Ajouter des utilisateurs',
|
||||||
Alert: 'Alerte',
|
Alert: 'Alerte',
|
||||||
alert: 'alerte',
|
alert: 'alerte',
|
||||||
alerts: 'alertes',
|
alerts: 'alertes',
|
||||||
|
|
|
@ -88,7 +88,7 @@ export default {
|
||||||
Activity: 'Atividade',
|
Activity: 'Atividade',
|
||||||
Add_Reaction: 'Reagir',
|
Add_Reaction: 'Reagir',
|
||||||
Add_Server: 'Adicionar servidor',
|
Add_Server: 'Adicionar servidor',
|
||||||
Add_user: 'Adicionar usuário',
|
Add_users: 'Adicionar usuário',
|
||||||
Alert: 'Alerta',
|
Alert: 'Alerta',
|
||||||
alert: 'alerta',
|
alert: 'alerta',
|
||||||
alerts: 'alertas',
|
alerts: 'alertas',
|
||||||
|
@ -123,6 +123,7 @@ export default {
|
||||||
Cancel: 'Cancelar',
|
Cancel: 'Cancelar',
|
||||||
changing_avatar: 'trocando avatar',
|
changing_avatar: 'trocando avatar',
|
||||||
creating_channel: 'criando canal',
|
creating_channel: 'criando canal',
|
||||||
|
creating_invite: 'criando convite',
|
||||||
Channel_Name: 'Nome do Canal',
|
Channel_Name: 'Nome do Canal',
|
||||||
Channels: 'Canais',
|
Channels: 'Canais',
|
||||||
Chats: 'Conversas',
|
Chats: 'Conversas',
|
||||||
|
@ -169,6 +170,7 @@ export default {
|
||||||
edited: 'editado',
|
edited: 'editado',
|
||||||
erasing_room: 'apagando sala',
|
erasing_room: 'apagando sala',
|
||||||
Edit: 'Editar',
|
Edit: 'Editar',
|
||||||
|
Edit_Invite: 'Editar convite',
|
||||||
Email_or_password_field_is_empty: 'Email ou senha estão vazios',
|
Email_or_password_field_is_empty: 'Email ou senha estão vazios',
|
||||||
Email: 'Email',
|
Email: 'Email',
|
||||||
email: 'e-mail',
|
email: 'e-mail',
|
||||||
|
@ -176,6 +178,7 @@ export default {
|
||||||
Enable_notifications: 'Habilitar notificações',
|
Enable_notifications: 'Habilitar notificações',
|
||||||
Everyone_can_access_this_channel: 'Todos podem acessar este canal',
|
Everyone_can_access_this_channel: 'Todos podem acessar este canal',
|
||||||
Error_uploading: 'Erro subindo',
|
Error_uploading: 'Erro subindo',
|
||||||
|
Expiration_Days: 'Expira em (dias)',
|
||||||
Favorites: 'Favoritos',
|
Favorites: 'Favoritos',
|
||||||
Files: 'Arquivos',
|
Files: 'Arquivos',
|
||||||
File_description: 'Descrição do arquivo',
|
File_description: 'Descrição do arquivo',
|
||||||
|
@ -188,6 +191,7 @@ export default {
|
||||||
Forgot_password: 'Esqueci minha senha',
|
Forgot_password: 'Esqueci minha senha',
|
||||||
Forgot_Password: 'Esqueci minha senha',
|
Forgot_Password: 'Esqueci minha senha',
|
||||||
Full_table: 'Clique para ver a tabela completa',
|
Full_table: 'Clique para ver a tabela completa',
|
||||||
|
Generate_New_Link: 'Gerar novo convite',
|
||||||
Group_by_favorites: 'Agrupar favoritos',
|
Group_by_favorites: 'Agrupar favoritos',
|
||||||
Group_by_type: 'Agrupar por tipo',
|
Group_by_type: 'Agrupar por tipo',
|
||||||
Has_joined_the_channel: 'Entrou no canal',
|
Has_joined_the_channel: 'Entrou no canal',
|
||||||
|
@ -196,7 +200,10 @@ export default {
|
||||||
Invisible: 'Invisível',
|
Invisible: 'Invisível',
|
||||||
Invite: 'Convidar',
|
Invite: 'Convidar',
|
||||||
is_typing: 'está digitando',
|
is_typing: 'está digitando',
|
||||||
|
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.',
|
||||||
|
Invite_Link: 'Link de Convite',
|
||||||
|
Invite_users: 'Convidar usuários',
|
||||||
Join_the_community: 'Junte-se à comunidade',
|
Join_the_community: 'Junte-se à comunidade',
|
||||||
Join: 'Entrar',
|
Join: 'Entrar',
|
||||||
Just_invited_people_can_access_this_channel: 'Apenas as pessoas convidadas podem acessar este canal',
|
Just_invited_people_can_access_this_channel: 'Apenas as pessoas convidadas podem acessar este canal',
|
||||||
|
@ -212,6 +219,7 @@ export default {
|
||||||
Login_error: 'Suas credenciais foram rejeitadas. Tente novamente por favor!',
|
Login_error: 'Suas credenciais foram rejeitadas. Tente novamente por favor!',
|
||||||
Login_with: 'Login with',
|
Login_with: 'Login with',
|
||||||
Logout: 'Sair',
|
Logout: 'Sair',
|
||||||
|
Max_number_of_uses: 'Número máximo de usos',
|
||||||
Members: 'Membros',
|
Members: 'Membros',
|
||||||
Mentioned_Messages: 'Mensagens mencionadas',
|
Mentioned_Messages: 'Mensagens mencionadas',
|
||||||
mentioned: 'mencionado',
|
mentioned: 'mencionado',
|
||||||
|
@ -231,11 +239,13 @@ export default {
|
||||||
N_users: '{{n}} usuários',
|
N_users: '{{n}} usuários',
|
||||||
name: 'nome',
|
name: 'nome',
|
||||||
Name: 'Nome',
|
Name: 'Nome',
|
||||||
|
Never: 'Nunca',
|
||||||
New_in_RocketChat_question_mark: 'Novo no Rocket.Chat?',
|
New_in_RocketChat_question_mark: 'Novo no Rocket.Chat?',
|
||||||
New_Message: 'Nova Mensagem',
|
New_Message: 'Nova Mensagem',
|
||||||
New_Password: 'Nova Senha',
|
New_Password: 'Nova Senha',
|
||||||
Next: 'Próximo',
|
Next: 'Próximo',
|
||||||
No_files: 'Não há arquivos',
|
No_files: 'Não há arquivos',
|
||||||
|
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',
|
||||||
|
@ -328,6 +338,7 @@ export default {
|
||||||
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',
|
||||||
Sign_in_your_server: 'Entrar no seu servidor',
|
Sign_in_your_server: 'Entrar no seu servidor',
|
||||||
Sign_Up: 'Registrar',
|
Sign_Up: 'Registrar',
|
||||||
Some_field_is_invalid_or_empty: 'Algum campo está inválido ou vazio',
|
Some_field_is_invalid_or_empty: 'Algum campo está inválido ou vazio',
|
||||||
|
@ -401,7 +412,10 @@ export default {
|
||||||
you_were_mentioned: 'você foi mencionado',
|
you_were_mentioned: 'você foi mencionado',
|
||||||
you: 'você',
|
you: 'você',
|
||||||
You: 'Você',
|
You: 'Você',
|
||||||
You_need_to_access_at_least_one_RocketChat_server_to_share_something: 'Você precisa acessar ao menos um servidor Rocket.Chat para compartilhar.',
|
Your_invite_link_will_expire_after__usesLeft__uses: 'Seu link de convite irá vencer depois de {{usesLeft}} usos.',
|
||||||
|
Your_invite_link_will_expire_on__date__or_after__usesLeft__uses: 'Seu link de convite irá vencer em {{date}} ou depois de {{usesLeft}} usos.',
|
||||||
|
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.',
|
||||||
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!',
|
||||||
Write_External_Permission_Message: 'Rocket Chat precisa de acesso à sua galeria para salvar imagens',
|
Write_External_Permission_Message: 'Rocket Chat precisa de acesso à sua galeria para salvar imagens',
|
||||||
Write_External_Permission: 'Acesso à Galeria',
|
Write_External_Permission: 'Acesso à Galeria',
|
||||||
|
|
|
@ -80,7 +80,7 @@ export default {
|
||||||
Activity: 'Actividade',
|
Activity: 'Actividade',
|
||||||
Add_Reaction: 'Adicionar Reacção',
|
Add_Reaction: 'Adicionar Reacção',
|
||||||
Add_Server: 'Adicionar Servidor',
|
Add_Server: 'Adicionar Servidor',
|
||||||
Add_user: 'Adicionar utilizador',
|
Add_users: 'Adicionar utilizadores',
|
||||||
Alert: 'Alerta',
|
Alert: 'Alerta',
|
||||||
alert: 'alerta',
|
alert: 'alerta',
|
||||||
alerts: 'alertas',
|
alerts: 'alertas',
|
||||||
|
|
|
@ -80,7 +80,7 @@ export default {
|
||||||
Activity: 'Активность',
|
Activity: 'Активность',
|
||||||
Add_Reaction: 'Добавить реакцию',
|
Add_Reaction: 'Добавить реакцию',
|
||||||
Add_Server: 'Добавить сервер',
|
Add_Server: 'Добавить сервер',
|
||||||
Add_user: 'Добавить пользователя',
|
Add_users: 'Добавить пользователей',
|
||||||
Admin_Panel: 'Панель админа',
|
Admin_Panel: 'Панель админа',
|
||||||
Alert: 'Оповещение',
|
Alert: 'Оповещение',
|
||||||
alert: 'оповещение',
|
alert: 'оповещение',
|
||||||
|
|
|
@ -80,7 +80,7 @@ export default {
|
||||||
Activity: '按活动排序',
|
Activity: '按活动排序',
|
||||||
Add_Reaction: '增加回复',
|
Add_Reaction: '增加回复',
|
||||||
Add_Server: '添加服务器',
|
Add_Server: '添加服务器',
|
||||||
Add_user: '添加用户',
|
Add_users: '添加用户',
|
||||||
Alert: '警告',
|
Alert: '警告',
|
||||||
alert: '警告',
|
alert: '警告',
|
||||||
alerts: '警告',
|
alerts: '警告',
|
||||||
|
|
|
@ -49,7 +49,7 @@ if (isIOS) {
|
||||||
const parseDeepLinking = (url) => {
|
const parseDeepLinking = (url) => {
|
||||||
if (url) {
|
if (url) {
|
||||||
url = url.replace(/rocketchat:\/\/|https:\/\/go.rocket.chat\//, '');
|
url = url.replace(/rocketchat:\/\/|https:\/\/go.rocket.chat\//, '');
|
||||||
const regex = /^(room|auth)\?/;
|
const regex = /^(room|auth|invite)\?/;
|
||||||
if (url.match(regex)) {
|
if (url.match(regex)) {
|
||||||
url = url.replace(regex, '').trim();
|
url = url.replace(regex, '').trim();
|
||||||
if (url) {
|
if (url) {
|
||||||
|
@ -146,6 +146,12 @@ const ChatsStack = createStackNavigator({
|
||||||
SelectedUsersView: {
|
SelectedUsersView: {
|
||||||
getScreen: () => require('./views/SelectedUsersView').default
|
getScreen: () => require('./views/SelectedUsersView').default
|
||||||
},
|
},
|
||||||
|
InviteUsersView: {
|
||||||
|
getScreen: () => require('./views/InviteUsersView').default
|
||||||
|
},
|
||||||
|
InviteUsersEditView: {
|
||||||
|
getScreen: () => require('./views/InviteUsersEditView').default
|
||||||
|
},
|
||||||
MessagesView: {
|
MessagesView: {
|
||||||
getScreen: () => require('./views/MessagesView').default
|
getScreen: () => require('./views/MessagesView').default
|
||||||
},
|
},
|
||||||
|
|
|
@ -1098,6 +1098,23 @@ const RocketChat = {
|
||||||
},
|
},
|
||||||
translateMessage(message, targetLanguage) {
|
translateMessage(message, targetLanguage) {
|
||||||
return this.sdk.methodCall('autoTranslate.translateMessage', message, targetLanguage);
|
return this.sdk.methodCall('autoTranslate.translateMessage', message, targetLanguage);
|
||||||
|
},
|
||||||
|
getRoomTitle(room) {
|
||||||
|
const { UI_Use_Real_Name: useRealName } = reduxStore.getState().settings;
|
||||||
|
return ((room.prid || useRealName) && room.fname) || room.name;
|
||||||
|
},
|
||||||
|
|
||||||
|
findOrCreateInvite({ rid, days, maxUses }) {
|
||||||
|
// RC 2.4.0
|
||||||
|
return this.sdk.post('findOrCreateInvite', { rid, days, maxUses });
|
||||||
|
},
|
||||||
|
validateInviteToken(token) {
|
||||||
|
// RC 2.4.0
|
||||||
|
return this.sdk.post('validateInviteToken', { token });
|
||||||
|
},
|
||||||
|
useInviteToken(token) {
|
||||||
|
// RC 2.4.0
|
||||||
|
return this.sdk.post('useInviteToken', { token });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import crashReport from './crashReport';
|
||||||
import customEmojis from './customEmojis';
|
import customEmojis from './customEmojis';
|
||||||
import activeUsers from './activeUsers';
|
import activeUsers from './activeUsers';
|
||||||
import usersTyping from './usersTyping';
|
import usersTyping from './usersTyping';
|
||||||
|
import inviteLinks from './inviteLinks';
|
||||||
|
|
||||||
export default combineReducers({
|
export default combineReducers({
|
||||||
settings,
|
settings,
|
||||||
|
@ -32,5 +33,6 @@ export default combineReducers({
|
||||||
crashReport,
|
crashReport,
|
||||||
customEmojis,
|
customEmojis,
|
||||||
activeUsers,
|
activeUsers,
|
||||||
usersTyping
|
usersTyping,
|
||||||
|
inviteLinks
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
import { INVITE_LINKS } from '../actions/actionsTypes';
|
||||||
|
|
||||||
|
const initialState = {
|
||||||
|
token: '',
|
||||||
|
days: 1,
|
||||||
|
maxUses: 0,
|
||||||
|
invite: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default (state = initialState, action) => {
|
||||||
|
switch (action.type) {
|
||||||
|
case INVITE_LINKS.SET_TOKEN:
|
||||||
|
return {
|
||||||
|
token: action.token
|
||||||
|
};
|
||||||
|
case INVITE_LINKS.SET_PARAMS:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
...action.params
|
||||||
|
};
|
||||||
|
case INVITE_LINKS.SET_INVITE:
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
invite: action.invite
|
||||||
|
};
|
||||||
|
case INVITE_LINKS.REQUEST:
|
||||||
|
return state;
|
||||||
|
case INVITE_LINKS.SUCCESS:
|
||||||
|
return initialState;
|
||||||
|
case INVITE_LINKS.FAILURE:
|
||||||
|
return initialState;
|
||||||
|
case INVITE_LINKS.CLEAR:
|
||||||
|
return initialState;
|
||||||
|
default:
|
||||||
|
return state;
|
||||||
|
}
|
||||||
|
};
|
|
@ -6,6 +6,7 @@ import RNUserDefaults from 'rn-user-defaults';
|
||||||
import Navigation from '../lib/Navigation';
|
import Navigation from '../lib/Navigation';
|
||||||
import * as types from '../actions/actionsTypes';
|
import * as types from '../actions/actionsTypes';
|
||||||
import { selectServerRequest } from '../actions/server';
|
import { selectServerRequest } from '../actions/server';
|
||||||
|
import { inviteLinksSetToken, inviteLinksRequest } from '../actions/inviteLinks';
|
||||||
import database from '../lib/database';
|
import database from '../lib/database';
|
||||||
import RocketChat from '../lib/rocketchat';
|
import RocketChat from '../lib/rocketchat';
|
||||||
import EventEmitter from '../utils/events';
|
import EventEmitter from '../utils/events';
|
||||||
|
@ -15,6 +16,17 @@ const roomTypes = {
|
||||||
channel: 'c', direct: 'd', group: 'p'
|
channel: 'c', direct: 'd', group: 'p'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleInviteLink = function* handleInviteLink({ params, requireLogin = false }) {
|
||||||
|
if (params.path && params.path.startsWith('invite/')) {
|
||||||
|
const token = params.path.replace('invite/', '');
|
||||||
|
if (requireLogin) {
|
||||||
|
yield put(inviteLinksSetToken(token));
|
||||||
|
} else {
|
||||||
|
yield put(inviteLinksRequest(token));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const navigate = function* navigate({ params }) {
|
const navigate = function* navigate({ params }) {
|
||||||
yield put(appStart('inside'));
|
yield put(appStart('inside'));
|
||||||
if (params.rid) {
|
if (params.rid) {
|
||||||
|
@ -24,6 +36,8 @@ const navigate = function* navigate({ params }) {
|
||||||
yield Navigation.navigate('RoomsListView');
|
yield Navigation.navigate('RoomsListView');
|
||||||
Navigation.navigate('RoomView', { rid: params.rid, name, t: roomTypes[type] });
|
Navigation.navigate('RoomView', { rid: params.rid, name, t: roomTypes[type] });
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
yield handleInviteLink({ params });
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -63,7 +77,7 @@ const handleOpen = function* handleOpen({ params }) {
|
||||||
const servers = yield serversCollection.find(host);
|
const servers = yield serversCollection.find(host);
|
||||||
if (servers && user) {
|
if (servers && user) {
|
||||||
yield put(selectServerRequest(host));
|
yield put(selectServerRequest(host));
|
||||||
yield take(types.SERVER.SELECT_SUCCESS);
|
yield take(types.LOGIN.SUCCESS);
|
||||||
yield navigate({ params });
|
yield navigate({ params });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -82,6 +96,8 @@ const handleOpen = function* handleOpen({ params }) {
|
||||||
if (params.token) {
|
if (params.token) {
|
||||||
yield take(types.SERVER.SELECT_SUCCESS);
|
yield take(types.SERVER.SELECT_SUCCESS);
|
||||||
yield RocketChat.connect({ server: host, user: { token: params.token } });
|
yield RocketChat.connect({ server: host, user: { token: params.token } });
|
||||||
|
} else {
|
||||||
|
yield handleInviteLink({ params, requireLogin: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -8,6 +8,7 @@ import createChannel from './createChannel';
|
||||||
import init from './init';
|
import init from './init';
|
||||||
import state from './state';
|
import state from './state';
|
||||||
import deepLinking from './deepLinking';
|
import deepLinking from './deepLinking';
|
||||||
|
import inviteLinks from './inviteLinks';
|
||||||
|
|
||||||
const root = function* root() {
|
const root = function* root() {
|
||||||
yield all([
|
yield all([
|
||||||
|
@ -19,7 +20,8 @@ const root = function* root() {
|
||||||
messages(),
|
messages(),
|
||||||
selectServer(),
|
selectServer(),
|
||||||
state(),
|
state(),
|
||||||
deepLinking()
|
deepLinking(),
|
||||||
|
inviteLinks()
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
import {
|
||||||
|
put, takeLatest, delay, select
|
||||||
|
} from 'redux-saga/effects';
|
||||||
|
import { Alert } from 'react-native';
|
||||||
|
|
||||||
|
import { INVITE_LINKS } from '../actions/actionsTypes';
|
||||||
|
import { inviteLinksSuccess, inviteLinksFailure, inviteLinksSetInvite } from '../actions/inviteLinks';
|
||||||
|
import RocketChat from '../lib/rocketchat';
|
||||||
|
import log from '../utils/log';
|
||||||
|
import Navigation from '../lib/Navigation';
|
||||||
|
import I18n from '../i18n';
|
||||||
|
|
||||||
|
const handleRequest = function* handleRequest({ token }) {
|
||||||
|
try {
|
||||||
|
const validateResult = yield RocketChat.validateInviteToken(token);
|
||||||
|
if (!validateResult.valid) {
|
||||||
|
yield put(inviteLinksFailure());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const result = yield RocketChat.useInviteToken(token);
|
||||||
|
if (!result.success) {
|
||||||
|
yield put(inviteLinksFailure());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.room && result.room.rid) {
|
||||||
|
yield delay(1000);
|
||||||
|
yield Navigation.navigate('RoomsListView');
|
||||||
|
const { room } = result;
|
||||||
|
Navigation.navigate('RoomView', {
|
||||||
|
rid: room.rid,
|
||||||
|
name: RocketChat.getRoomTitle(room),
|
||||||
|
t: room.t
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
yield put(inviteLinksSuccess());
|
||||||
|
} catch (e) {
|
||||||
|
yield put(inviteLinksFailure());
|
||||||
|
log(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleFailure = function handleFailure() {
|
||||||
|
Alert.alert(I18n.t('Oops'), I18n.t('Invalid_or_expired_invite_token'));
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleCreateInviteLink = function* handleCreateInviteLink({ rid }) {
|
||||||
|
try {
|
||||||
|
const inviteLinks = yield select(state => state.inviteLinks);
|
||||||
|
const result = yield RocketChat.findOrCreateInvite({
|
||||||
|
rid, days: inviteLinks.days, maxUses: inviteLinks.maxUses
|
||||||
|
});
|
||||||
|
if (!result.success) {
|
||||||
|
Alert.alert(I18n.t('Oops'), I18n.t('There_was_an_error_while_action', { action: I18n.t('creating_invite') }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield put(inviteLinksSetInvite(result));
|
||||||
|
} catch (e) {
|
||||||
|
log(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const root = function* root() {
|
||||||
|
yield takeLatest(INVITE_LINKS.REQUEST, handleRequest);
|
||||||
|
yield takeLatest(INVITE_LINKS.FAILURE, handleFailure);
|
||||||
|
yield takeLatest(INVITE_LINKS.CREATE, handleCreateInviteLink);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default root;
|
|
@ -20,6 +20,7 @@ import I18n from '../i18n';
|
||||||
import database from '../lib/database';
|
import database from '../lib/database';
|
||||||
import EventEmitter from '../utils/events';
|
import EventEmitter from '../utils/events';
|
||||||
import Navigation from '../lib/Navigation';
|
import Navigation from '../lib/Navigation';
|
||||||
|
import { inviteLinksRequest } from '../actions/inviteLinks';
|
||||||
|
|
||||||
const getServer = state => state.server.server;
|
const getServer = state => state.server.server;
|
||||||
const loginWithPasswordCall = args => RocketChat.loginWithPassword(args);
|
const loginWithPasswordCall = args => RocketChat.loginWithPassword(args);
|
||||||
|
@ -115,17 +116,27 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) {
|
||||||
yield put(setUser(user));
|
yield put(setUser(user));
|
||||||
EventEmitter.emit('connected');
|
EventEmitter.emit('connected');
|
||||||
|
|
||||||
|
let currentRoot;
|
||||||
if (!user.username) {
|
if (!user.username) {
|
||||||
yield put(appStart('setUsername'));
|
yield put(appStart('setUsername'));
|
||||||
} else if (adding) {
|
} else if (adding) {
|
||||||
yield put(serverFinishAdd());
|
yield put(serverFinishAdd());
|
||||||
yield put(appStart('inside'));
|
yield put(appStart('inside'));
|
||||||
} else {
|
} else {
|
||||||
const currentRoot = yield select(state => state.app.root);
|
currentRoot = yield select(state => state.app.root);
|
||||||
if (currentRoot !== 'inside') {
|
if (currentRoot !== 'inside') {
|
||||||
yield put(appStart('inside'));
|
yield put(appStart('inside'));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// after a successful login, check if it's been invited via invite link
|
||||||
|
currentRoot = yield select(state => state.app.root);
|
||||||
|
if (currentRoot === 'inside') {
|
||||||
|
const inviteLinkToken = yield select(state => state.inviteLinks.token);
|
||||||
|
if (inviteLinkToken) {
|
||||||
|
yield put(inviteLinksRequest(inviteLinkToken));
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
log(e);
|
log(e);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,160 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { ScrollView, View } from 'react-native';
|
||||||
|
import { SafeAreaView } from 'react-navigation';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import RNPickerSelect from 'react-native-picker-select';
|
||||||
|
|
||||||
|
import {
|
||||||
|
inviteLinksSetParams as inviteLinksSetParamsAction,
|
||||||
|
inviteLinksCreate as inviteLinksCreateAction
|
||||||
|
} from '../../actions/inviteLinks';
|
||||||
|
import ListItem from '../../containers/ListItem';
|
||||||
|
import styles from './styles';
|
||||||
|
import Button from '../../containers/Button';
|
||||||
|
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||||
|
import I18n from '../../i18n';
|
||||||
|
import StatusBar from '../../containers/StatusBar';
|
||||||
|
import { themes } from '../../constants/colors';
|
||||||
|
import { withTheme } from '../../theme';
|
||||||
|
import { themedHeader } from '../../utils/navigation';
|
||||||
|
import Separator from '../../containers/Separator';
|
||||||
|
|
||||||
|
const OPTIONS = {
|
||||||
|
days: [{
|
||||||
|
label: I18n.t('Never'), value: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '1', value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '7', value: 7
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '15', value: 15
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '30', value: 30
|
||||||
|
}],
|
||||||
|
maxUses: [{
|
||||||
|
label: I18n.t('No_limit'), value: 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '1', value: 1
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '5', value: 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '10', value: 10
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '25', value: 25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '50', value: 50
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: '100', value: 100
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
class InviteUsersView extends React.Component {
|
||||||
|
static navigationOptions = ({ screenProps }) => ({
|
||||||
|
title: I18n.t('Invite_users'),
|
||||||
|
...themedHeader(screenProps.theme)
|
||||||
|
})
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
navigation: PropTypes.object,
|
||||||
|
theme: PropTypes.string,
|
||||||
|
timeDateFormat: PropTypes.string,
|
||||||
|
createInviteLink: PropTypes.func,
|
||||||
|
inviteLinksSetParams: PropTypes.func
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.rid = props.navigation.getParam('rid');
|
||||||
|
}
|
||||||
|
|
||||||
|
onValueChangePicker = (key, value) => {
|
||||||
|
const { inviteLinksSetParams } = this.props;
|
||||||
|
const params = {
|
||||||
|
[key]: value
|
||||||
|
};
|
||||||
|
inviteLinksSetParams(params);
|
||||||
|
}
|
||||||
|
|
||||||
|
createInviteLink = () => {
|
||||||
|
const { createInviteLink, navigation } = this.props;
|
||||||
|
createInviteLink(this.rid);
|
||||||
|
navigation.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
renderPicker = (key) => {
|
||||||
|
const { props } = this;
|
||||||
|
const { theme } = props;
|
||||||
|
return (
|
||||||
|
<RNPickerSelect
|
||||||
|
style={{ viewContainer: styles.viewContainer }}
|
||||||
|
value={props[key]}
|
||||||
|
textInputProps={{ style: { ...styles.pickerText, color: themes[theme].actionTintColor } }}
|
||||||
|
useNativeAndroidPickerStyle={false}
|
||||||
|
placeholder={{}}
|
||||||
|
onValueChange={value => this.onValueChangePicker(key, value)}
|
||||||
|
items={OPTIONS[key]}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { theme } = this.props;
|
||||||
|
return (
|
||||||
|
<SafeAreaView style={[styles.container, { backgroundColor: themes[theme].backgroundColor }]} forceInset={{ vertical: 'never' }}>
|
||||||
|
<ScrollView
|
||||||
|
{...scrollPersistTaps}
|
||||||
|
style={{ backgroundColor: themes[theme].auxiliaryBackground }}
|
||||||
|
contentContainerStyle={styles.contentContainer}
|
||||||
|
showsVerticalScrollIndicator={false}
|
||||||
|
>
|
||||||
|
<StatusBar theme={theme} />
|
||||||
|
<Separator theme={theme} />
|
||||||
|
<ListItem
|
||||||
|
title={I18n.t('Expiration_Days')}
|
||||||
|
right={() => this.renderPicker('days')}
|
||||||
|
theme={theme}
|
||||||
|
/>
|
||||||
|
<Separator theme={theme} />
|
||||||
|
<ListItem
|
||||||
|
title={I18n.t('Max_number_of_uses')}
|
||||||
|
right={() => this.renderPicker('maxUses')}
|
||||||
|
theme={theme}
|
||||||
|
/>
|
||||||
|
<Separator theme={theme} />
|
||||||
|
<View style={styles.innerContainer}>
|
||||||
|
<View style={[styles.divider, { backgroundColor: themes[theme].separatorColor }]} />
|
||||||
|
<Button
|
||||||
|
title={I18n.t('Generate_New_Link')}
|
||||||
|
type='primary'
|
||||||
|
onPress={this.createInviteLink}
|
||||||
|
theme={theme}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
days: state.inviteLinks.days,
|
||||||
|
maxUses: state.inviteLinks.maxUses
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
inviteLinksSetParams: params => dispatch(inviteLinksSetParamsAction(params)),
|
||||||
|
createInviteLink: rid => dispatch(inviteLinksCreateAction(rid))
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(InviteUsersView));
|
|
@ -0,0 +1,45 @@
|
||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
import sharedStyles from '../Styles';
|
||||||
|
|
||||||
|
export default StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1
|
||||||
|
},
|
||||||
|
innerContainer: {
|
||||||
|
paddingHorizontal: 20
|
||||||
|
},
|
||||||
|
divider: {
|
||||||
|
width: '100%',
|
||||||
|
height: StyleSheet.hairlineWidth,
|
||||||
|
marginVertical: 20
|
||||||
|
},
|
||||||
|
sectionSeparatorBorder: {
|
||||||
|
height: 10
|
||||||
|
},
|
||||||
|
marginBottom: {
|
||||||
|
height: 30
|
||||||
|
},
|
||||||
|
contentContainer: {
|
||||||
|
marginVertical: 10
|
||||||
|
},
|
||||||
|
infoText: {
|
||||||
|
...sharedStyles.textRegular,
|
||||||
|
fontSize: 13,
|
||||||
|
paddingHorizontal: 15,
|
||||||
|
paddingVertical: 10
|
||||||
|
},
|
||||||
|
sectionTitle: {
|
||||||
|
...sharedStyles.separatorBottom,
|
||||||
|
paddingHorizontal: 15,
|
||||||
|
paddingVertical: 10,
|
||||||
|
fontSize: 14
|
||||||
|
},
|
||||||
|
viewContainer: {
|
||||||
|
justifyContent: 'center'
|
||||||
|
},
|
||||||
|
pickerText: {
|
||||||
|
...sharedStyles.textRegular,
|
||||||
|
fontSize: 16
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,151 @@
|
||||||
|
import React from 'react';
|
||||||
|
import PropTypes from 'prop-types';
|
||||||
|
import { View, Share, ScrollView } from 'react-native';
|
||||||
|
import { SafeAreaView } from 'react-navigation';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
|
||||||
|
import {
|
||||||
|
inviteLinksCreate as inviteLinksCreateAction,
|
||||||
|
inviteLinksClear as inviteLinksClearAction
|
||||||
|
} from '../../actions/inviteLinks';
|
||||||
|
import RCTextInput from '../../containers/TextInput';
|
||||||
|
import styles from './styles';
|
||||||
|
import Markdown from '../../containers/markdown';
|
||||||
|
import Button from '../../containers/Button';
|
||||||
|
import scrollPersistTaps from '../../utils/scrollPersistTaps';
|
||||||
|
import I18n from '../../i18n';
|
||||||
|
import StatusBar from '../../containers/StatusBar';
|
||||||
|
import { themes } from '../../constants/colors';
|
||||||
|
import { withTheme } from '../../theme';
|
||||||
|
import { themedHeader } from '../../utils/navigation';
|
||||||
|
|
||||||
|
class InviteUsersView extends React.Component {
|
||||||
|
static navigationOptions = ({ screenProps }) => ({
|
||||||
|
title: I18n.t('Invite_users'),
|
||||||
|
...themedHeader(screenProps.theme)
|
||||||
|
})
|
||||||
|
|
||||||
|
static propTypes = {
|
||||||
|
navigation: PropTypes.object,
|
||||||
|
theme: PropTypes.string,
|
||||||
|
timeDateFormat: PropTypes.string,
|
||||||
|
invite: PropTypes.object,
|
||||||
|
createInviteLink: PropTypes.func,
|
||||||
|
clearInviteLink: PropTypes.func
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.rid = props.navigation.getParam('rid');
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
const { createInviteLink } = this.props;
|
||||||
|
createInviteLink(this.rid);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
const { clearInviteLink } = this.props;
|
||||||
|
clearInviteLink();
|
||||||
|
}
|
||||||
|
|
||||||
|
share = () => {
|
||||||
|
const { invite } = this.props;
|
||||||
|
if (!invite) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Share.share({ message: invite.url });
|
||||||
|
}
|
||||||
|
|
||||||
|
edit = () => {
|
||||||
|
const { navigation } = this.props;
|
||||||
|
navigation.navigate('InviteUsersEditView', { rid: this.rid });
|
||||||
|
}
|
||||||
|
|
||||||
|
linkExpirationText = () => {
|
||||||
|
const { timeDateFormat, invite } = this.props;
|
||||||
|
|
||||||
|
if (!invite || !invite.url) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invite.expires) {
|
||||||
|
const expiration = new Date(invite.expires);
|
||||||
|
|
||||||
|
if (invite.maxUses) {
|
||||||
|
const usesLeft = invite.maxUses - invite.uses;
|
||||||
|
return I18n.t('Your_invite_link_will_expire_on__date__or_after__usesLeft__uses', { date: moment(expiration).format(timeDateFormat), usesLeft });
|
||||||
|
}
|
||||||
|
|
||||||
|
return I18n.t('Your_invite_link_will_expire_on__date__', { date: moment(expiration).format(timeDateFormat) });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (invite.maxUses) {
|
||||||
|
const usesLeft = invite.maxUses - invite.uses;
|
||||||
|
return I18n.t('Your_invite_link_will_expire_after__usesLeft__uses', { usesLeft });
|
||||||
|
}
|
||||||
|
|
||||||
|
return I18n.t('Your_invite_link_will_never_expire');
|
||||||
|
}
|
||||||
|
|
||||||
|
renderExpiration = () => {
|
||||||
|
const { theme } = this.props;
|
||||||
|
const expirationMessage = this.linkExpirationText();
|
||||||
|
return <Markdown msg={expirationMessage} username='' baseUrl='' theme={theme} />;
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const {
|
||||||
|
theme, invite
|
||||||
|
} = this.props;
|
||||||
|
return (
|
||||||
|
<SafeAreaView style={[styles.container, { backgroundColor: themes[theme].backgroundColor }]} forceInset={{ vertical: 'never' }}>
|
||||||
|
<ScrollView
|
||||||
|
{...scrollPersistTaps}
|
||||||
|
style={{ backgroundColor: themes[theme].auxiliaryBackground }}
|
||||||
|
contentContainerStyle={styles.contentContainer}
|
||||||
|
showsVerticalScrollIndicator={false}
|
||||||
|
>
|
||||||
|
<StatusBar theme={theme} />
|
||||||
|
<View style={styles.innerContainer}>
|
||||||
|
<RCTextInput
|
||||||
|
label={I18n.t('Invite_Link')}
|
||||||
|
theme={theme}
|
||||||
|
value={invite && invite.url}
|
||||||
|
editable={false}
|
||||||
|
/>
|
||||||
|
{this.renderExpiration()}
|
||||||
|
<View style={[styles.divider, { backgroundColor: themes[theme].separatorColor }]} />
|
||||||
|
<Button
|
||||||
|
title={I18n.t('Share_Link')}
|
||||||
|
type='primary'
|
||||||
|
onPress={this.share}
|
||||||
|
theme={theme}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
title={I18n.t('Edit_Invite')}
|
||||||
|
type='secondary'
|
||||||
|
onPress={this.edit}
|
||||||
|
theme={theme}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
</ScrollView>
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
timeDateFormat: state.settings.Message_TimeAndDateFormat,
|
||||||
|
days: state.inviteLinks.days,
|
||||||
|
maxUses: state.inviteLinks.maxUses,
|
||||||
|
invite: state.inviteLinks.invite
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
createInviteLink: rid => dispatch(inviteLinksCreateAction(rid)),
|
||||||
|
clearInviteLink: () => dispatch(inviteLinksClearAction())
|
||||||
|
});
|
||||||
|
|
||||||
|
export default connect(mapStateToProps, mapDispatchToProps)(withTheme(InviteUsersView));
|
|
@ -0,0 +1,16 @@
|
||||||
|
import { StyleSheet } from 'react-native';
|
||||||
|
|
||||||
|
export default StyleSheet.create({
|
||||||
|
container: {
|
||||||
|
flex: 1
|
||||||
|
},
|
||||||
|
innerContainer: {
|
||||||
|
padding: 20,
|
||||||
|
paddingBottom: 0
|
||||||
|
},
|
||||||
|
divider: {
|
||||||
|
width: '100%',
|
||||||
|
height: StyleSheet.hairlineWidth,
|
||||||
|
marginVertical: 20
|
||||||
|
}
|
||||||
|
});
|
|
@ -62,7 +62,8 @@ class RoomActionsView extends React.Component {
|
||||||
joined: !!room,
|
joined: !!room,
|
||||||
canViewMembers: false,
|
canViewMembers: false,
|
||||||
canAutoTranslate: false,
|
canAutoTranslate: false,
|
||||||
canAddUser: false
|
canAddUser: false,
|
||||||
|
canInviteUser: false
|
||||||
};
|
};
|
||||||
if (room && room.observe && room.rid) {
|
if (room && room.observe && room.rid) {
|
||||||
this.roomObservable = room.observe();
|
this.roomObservable = room.observe();
|
||||||
|
@ -108,6 +109,7 @@ class RoomActionsView extends React.Component {
|
||||||
this.setState({ canAutoTranslate });
|
this.setState({ canAutoTranslate });
|
||||||
|
|
||||||
this.canAddUser();
|
this.canAddUser();
|
||||||
|
this.canInviteUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillUnmount() {
|
componentWillUnmount() {
|
||||||
|
@ -126,7 +128,6 @@ class RoomActionsView extends React.Component {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move to componentDidMount
|
|
||||||
// eslint-disable-next-line react/sort-comp
|
// eslint-disable-next-line react/sort-comp
|
||||||
canAddUser = async() => {
|
canAddUser = async() => {
|
||||||
const { room, joined } = this.state;
|
const { room, joined } = this.state;
|
||||||
|
@ -150,8 +151,15 @@ class RoomActionsView extends React.Component {
|
||||||
this.setState({ canAddUser: canAdd });
|
this.setState({ canAddUser: canAdd });
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move to componentDidMount
|
canInviteUser = async() => {
|
||||||
// eslint-disable-next-line react/sort-comp
|
const { room } = this.state;
|
||||||
|
const { rid } = room;
|
||||||
|
const permissions = await RocketChat.hasPermission(['create-invite-links'], rid);
|
||||||
|
|
||||||
|
const canInviteUser = permissions && permissions['create-invite-links'];
|
||||||
|
this.setState({ canInviteUser });
|
||||||
|
}
|
||||||
|
|
||||||
canViewMembers = async() => {
|
canViewMembers = async() => {
|
||||||
const { room } = this.state;
|
const { room } = this.state;
|
||||||
const { rid, t, broadcast } = room;
|
const { rid, t, broadcast } = room;
|
||||||
|
@ -172,7 +180,7 @@ class RoomActionsView extends React.Component {
|
||||||
|
|
||||||
get sections() {
|
get sections() {
|
||||||
const {
|
const {
|
||||||
room, membersCount, canViewMembers, canAddUser, joined, canAutoTranslate
|
room, membersCount, canViewMembers, canAddUser, canInviteUser, joined, canAutoTranslate
|
||||||
} = this.state;
|
} = this.state;
|
||||||
const { jitsiEnabled } = this.props;
|
const { jitsiEnabled } = this.props;
|
||||||
const {
|
const {
|
||||||
|
@ -302,17 +310,28 @@ class RoomActionsView extends React.Component {
|
||||||
|
|
||||||
if (canAddUser) {
|
if (canAddUser) {
|
||||||
actions.push({
|
actions.push({
|
||||||
icon: 'user-plus',
|
icon: 'plus',
|
||||||
name: I18n.t('Add_user'),
|
name: I18n.t('Add_users'),
|
||||||
route: 'SelectedUsersView',
|
route: 'SelectedUsersView',
|
||||||
params: {
|
params: {
|
||||||
nextActionID: 'ADD_USER',
|
nextActionID: 'ADD_USER',
|
||||||
rid,
|
rid,
|
||||||
title: I18n.t('Add_user')
|
title: I18n.t('Add_users')
|
||||||
},
|
},
|
||||||
testID: 'room-actions-add-user'
|
testID: 'room-actions-add-user'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if (canInviteUser) {
|
||||||
|
actions.push({
|
||||||
|
icon: 'user-plus',
|
||||||
|
name: I18n.t('Invite_users'),
|
||||||
|
route: 'InviteUsersView',
|
||||||
|
params: {
|
||||||
|
rid
|
||||||
|
},
|
||||||
|
testID: 'room-actions-invite-user'
|
||||||
|
});
|
||||||
|
}
|
||||||
sections[2].data = [...actions, ...sections[2].data];
|
sections[2].data = [...actions, ...sections[2].data];
|
||||||
|
|
||||||
if (joined) {
|
if (joined) {
|
||||||
|
|
|
@ -161,7 +161,6 @@ class RoomsListView extends React.Component {
|
||||||
groupByType: PropTypes.bool,
|
groupByType: PropTypes.bool,
|
||||||
showFavorites: PropTypes.bool,
|
showFavorites: PropTypes.bool,
|
||||||
showUnread: PropTypes.bool,
|
showUnread: PropTypes.bool,
|
||||||
useRealName: PropTypes.bool,
|
|
||||||
StoreLastMessage: PropTypes.bool,
|
StoreLastMessage: PropTypes.bool,
|
||||||
appState: PropTypes.string,
|
appState: PropTypes.string,
|
||||||
theme: PropTypes.string,
|
theme: PropTypes.string,
|
||||||
|
@ -486,10 +485,7 @@ class RoomsListView extends React.Component {
|
||||||
});
|
});
|
||||||
}, 300);
|
}, 300);
|
||||||
|
|
||||||
getRoomTitle = (item) => {
|
getRoomTitle = item => RocketChat.getRoomTitle(item)
|
||||||
const { useRealName } = this.props;
|
|
||||||
return ((item.prid || useRealName) && item.fname) || item.name;
|
|
||||||
};
|
|
||||||
|
|
||||||
goRoom = (item) => {
|
goRoom = (item) => {
|
||||||
this.cancelSearchingAndroid();
|
this.cancelSearchingAndroid();
|
||||||
|
|
Loading…
Reference in New Issue