mirror of
https://gitlab.opencode.de/bwi/bundesmessenger/clients/bundesmessenger-ios.git
synced 2026-04-22 01:22:46 +02:00
Merge branch gil/5230_SP2-Adding_Rooms_to_Spaces into gil/5231_SP3-1_Update_room_settings_for_Spaces
This commit is contained in:
@@ -504,3 +504,5 @@
|
||||
"attachment_unsupported_preview_message" = "Dieser Dateityp wird nicht unterstützt.";
|
||||
"attachment_unsupported_preview_title" = "Vorschau kann nicht angezeigt werden";
|
||||
"auth_reset_password_error_unauthorized" = "Nicht Authorisiert";
|
||||
"message_reply_to_sender_sent_their_location" = "hat den eigenen Standort geteilt.";
|
||||
"room_displayname_all_other_members_left" = "%@ (Verlassen)";
|
||||
|
||||
@@ -270,7 +270,7 @@
|
||||
// Language picker
|
||||
"language_picker_title" = "Vali keel";
|
||||
"language_picker_default_language" = "Vaikimisi (%@)";
|
||||
"notice_room_invite" = "%@ kutsus kasutajat %@";
|
||||
"notice_room_invite" = "%@ saatis kutse kasutajale %@";
|
||||
"notice_room_third_party_invite" = "%@ saatis kasutajale %@ kutse jututoaga liitumiseks";
|
||||
"notice_room_third_party_registered_invite" = "%@ võttis vastu kutse %@ nimel";
|
||||
"notice_room_third_party_revoked_invite" = "%@ võttis tagasi jututoaga liitumise kutse kasutajalt %@";
|
||||
@@ -433,7 +433,7 @@
|
||||
"notice_room_history_visible_to_members_from_invited_point_for_dm" = "%@ määras, et jututoa tulevane ajalugu on nähtav kõikidele selle liikmetele liitumiskutse saatmise hetkest.";
|
||||
"notice_room_history_visible_to_members_from_joined_point_for_dm" = "%@ määras, et jututoa tulevane ajalugu on nähtav kõikidele selle liikmetele nende liitumise hetkest.";
|
||||
"room_left_for_dm" = "Sina lahkusid";
|
||||
"notice_room_third_party_invite_for_dm" = "%@ kutsus kasutajat %@";
|
||||
"notice_room_third_party_invite_for_dm" = "%@ saatis kutse kasutajale %@";
|
||||
"notice_room_third_party_revoked_invite_for_dm" = "%@ võttis tagasi kasutaja %@ kutse";
|
||||
"notice_room_name_changed_for_dm" = "%@ muutis jututoa uueks nimeks %@.";
|
||||
"notice_room_third_party_invite_by_you_for_dm" = "Sina kutsusid kasutajat %@";
|
||||
@@ -478,3 +478,4 @@
|
||||
"room_displayname_all_other_members_left" = "%@ (lahkus(id))";
|
||||
"attachment_unsupported_preview_message" = "See failitüüp ei ole toetatud.";
|
||||
"attachment_unsupported_preview_title" = "Eelvaate kuvamine ei õnnestu";
|
||||
"message_reply_to_sender_sent_their_location" = "on jaganud oma asukohta.";
|
||||
|
||||
@@ -275,7 +275,7 @@
|
||||
"notice_conference_call_started" = "Téléconférence en VoIP démarrée";
|
||||
"notice_conference_call_finished" = "Téléconférence en VoIP terminée";
|
||||
// button names
|
||||
"ok" = "OK";
|
||||
"ok" = "Ok";
|
||||
"send" = "Envoyer";
|
||||
"copy_button_name" = "Copier";
|
||||
"resend" = "Renvoyer";
|
||||
|
||||
@@ -283,7 +283,7 @@
|
||||
"notice_conference_call_started" = "VoIP konferencia indult";
|
||||
"notice_conference_call_finished" = "VoIP konferencia befejeződött";
|
||||
// button names
|
||||
"ok" = "Rendben";
|
||||
"ok" = "OK";
|
||||
"cancel" = "Mégse";
|
||||
"save" = "Ment";
|
||||
"send" = "Küld";
|
||||
@@ -479,3 +479,4 @@
|
||||
"room_displayname_all_other_members_left" = "%@ (Bal)";
|
||||
"attachment_unsupported_preview_message" = "Ez a fájl típus nem támogatott.";
|
||||
"attachment_unsupported_preview_title" = "Az előnézetet nem lehet megjeleníteni";
|
||||
"message_reply_to_sender_sent_their_location" = "megosztotta a földrajzi helyzetét.";
|
||||
|
||||
@@ -249,7 +249,7 @@
|
||||
// titles
|
||||
|
||||
// button names
|
||||
"ok" = "OK";
|
||||
"ok" = "OKE";
|
||||
"notice_room_history_visible_to_members_from_joined_point_by_you_for_dm" = "Anda membuat sejarah pesan di masa mendatang dapat dilihat oleh semuanya, sejak mereka bergabung.";
|
||||
"notice_room_history_visible_to_members_from_joined_point_by_you" = "Anda membuat sejarah ruangan di masa mendatang dapat dilihat oleh semua anggota ruang, sejak mereka bergabung.";
|
||||
"notice_encryption_enabled_unknown_algorithm_by_you" = "Anda mengaktifkan enkripsi ujung-ke-ujung (algoritma %@ tidak dikenal).";
|
||||
@@ -557,3 +557,4 @@
|
||||
"notice_room_power_level_acting_requirement" = "Tingkat daya minimum yang harus dimiliki pengguna sebelum bertindak adalah:";
|
||||
"attachment_unsupported_preview_title" = "Tidak dapat ditampilkan";
|
||||
"attachment_unsupported_preview_message" = "Tipe file ini tidak didukung.";
|
||||
"message_reply_to_sender_sent_their_location" = "telah membagikan lokasinya.";
|
||||
|
||||
@@ -478,3 +478,4 @@
|
||||
"rename" = "Rinomina";
|
||||
"attachment_unsupported_preview_message" = "Questo tipo di file non è supportato.";
|
||||
"attachment_unsupported_preview_title" = "Anteprima non disponibile";
|
||||
"message_reply_to_sender_sent_their_location" = "ha condiviso la sua posizione.";
|
||||
|
||||
@@ -311,7 +311,7 @@
|
||||
// titles
|
||||
|
||||
// button names
|
||||
"ok" = "Oké";
|
||||
"ok" = "OK";
|
||||
"cancel" = "Annuleren";
|
||||
"save" = "Opslaan";
|
||||
"leave" = "Verlaten";
|
||||
@@ -540,3 +540,4 @@
|
||||
"room_displayname_all_other_members_left" = "%@ (Vertrok)";
|
||||
"auth_username_in_use" = "Inlognaam al in gebruik";
|
||||
"rename" = "Hernoemen";
|
||||
"message_reply_to_sender_sent_their_location" = "deelde hun locatie.";
|
||||
|
||||
@@ -496,3 +496,12 @@
|
||||
"attachment_small_with_resolution" = "Mały %@ (~%@)";
|
||||
"attachment_size_prompt_message" = "Możesz to wyłączyć w ustawieniach.";
|
||||
"attachment_size_prompt_title" = "Potwierdź rozmiar, który chcesz wysłać";
|
||||
"auth_reset_password_error_not_found" = "Nie znaleziono";
|
||||
"auth_reset_password_error_unauthorized" = "Brak autoryzacji";
|
||||
"auth_invalid_user_name" = "Niepoprawna nazwa użytkownika";
|
||||
"attachment_unsupported_preview_message" = "Ten format pliku nie jest obsługiwany.";
|
||||
"attachment_unsupported_preview_title" = "Brak podglądu";
|
||||
"message_reply_to_sender_sent_their_location" = "udostępnił(-a) swoją lokację.";
|
||||
"room_displayname_all_other_members_left" = "%@ (Opuścił-a)";
|
||||
"auth_username_in_use" = "Nazwa użytkownika jest już używana";
|
||||
"rename" = "Zmień nazwę";
|
||||
|
||||
@@ -121,7 +121,7 @@
|
||||
"room_displayname_two_members" = "%@ e %@";
|
||||
"room_displayname_more_than_two_members" = "%@ e %@ outros";
|
||||
// Settings
|
||||
"settings" = "Configurações";
|
||||
"settings" = "Ajustes";
|
||||
"settings_enable_inapp_notifications" = "Habilitar notificações Em-App";
|
||||
"settings_enable_push_notifications" = "Habilitar notificações push";
|
||||
"settings_enter_validation_token_for" = "Entrar token de validação para %@:";
|
||||
@@ -157,7 +157,7 @@
|
||||
"room_event_encryption_info_block" = "Adicionar à lista negra";
|
||||
"room_event_encryption_info_unblock" = "Remover da lista negra";
|
||||
"room_event_encryption_verify_title" = "Verificar sessão\n\n";
|
||||
"room_event_encryption_verify_message" = "Para verificar que esta sessão pode ser confiada, por favor contacte a/o dona(o) dela usando alguma outro meio (e.g. em pessoa ou uma chamada de telefone) e pergunte-lhe se a chave que ela/ele vê em suas Configurações de Usuária(o) para esta sessão bate com a chave abaixo:\n\n\tNome de sessão: %@\n\tID de sessão: %@\n\tChave de sessão: %@\n\nSe ela bate, pressione o botão verificar abaixo. Se não bate, então alguma outra pessoa está interceptando esa sessão e você provavelmente quer pressionar o botão adicionar à lista negra em vez disso.\n\nNo futuro este processo de verificação vai ser mais sofisticado.";
|
||||
"room_event_encryption_verify_message" = "Para verificar que esta sessão pode ser confiada, por favor contacte a/o dona(o) dela usando alguma outro meio (e.g. em pessoa ou uma chamada de telefone) e pergunte-lhe se a chave que ela/ele vê em seus Ajustes de Usuária(o) para esta sessão corresponde com a chave abaixo:\n\n\tNome de sessão: %@\n\tID de sessão: %@\n\tChave de sessão: %@\n\nSe ela corresponde, pressione o botão verificar abaixo. Se não corresponde, então alguma outra pessoa está interceptando esa sessão e você provavelmente quer pressionar o botão adicionar à lista negra em vez disso.\n\nNo futuro este processo de verificação vai ser mais sofisticado.";
|
||||
"room_event_encryption_verify_ok" = "Verificar";
|
||||
// Account
|
||||
"account_save_changes" = "Salvar mudanças";
|
||||
@@ -331,9 +331,9 @@
|
||||
"notification_settings_disable_all" = "Desabilitar todas as notificações";
|
||||
"notification_settings_enable_notifications" = "Habilitar notificações";
|
||||
"notification_settings_enable_notifications_warning" = "Todas as notificações estão atualmente desabilitadas para todos os dispositivos.";
|
||||
"notification_settings_global_info" = "Configurações de notificação são salvas em sua conta de usuária(o) e são compartilhadas entre todos os clientes que as suportam (incluindo notificações de desktop).\n\nRegras são aplicadas em ordem; a primeira regra que corresponde define o resultado da mensagem.\nEntão: Notificações per-palavra são mais importantes que notificações per-sala que são mais importantes que notificações per-enviador(a).\nPara múltiplas regras do mesmo tipo, a primeira na lista que corresponde leva prioridade.";
|
||||
"notification_settings_global_info" = "Ajustes de notificação são salvas em sua conta de usuária(o) e são compartilhadas entre todos os clientes que as suportam (incluindo notificações de desktop).\n\nRegras são aplicadas em ordem; a primeira regra que corresponde define o resultado da mensagem.\nEntão: Notificações per-palavra são mais importantes que notificações per-sala que são mais importantes que notificações per-enviador(a).\nPara múltiplas regras do mesmo tipo, a primeira na lista que corresponde leva prioridade.";
|
||||
"notification_settings_per_word_notifications" = "Notificações per-palavra";
|
||||
"notification_settings_per_word_info" = "Palavras correspondem insensivelmente a maiúsculas e minúsculas, e podem incluir um wildcard *. Então:\nfoo corresponde a string foo rodeado por delimitadores de palavras (e.g., pontuação e whitespace ou início/fim de linha).\nfoo* corresponde a qualquer palavra que começa foo.\n*foo* corresponde a qualquer palavra que inclui as 3 letras foo.";
|
||||
"notification_settings_per_word_info" = "Palavras correspondem insensivelmente com maiúsculas e minúsculas, e podem incluir um wildcard *. Então:\nfoo corresponde com string foo rodeado por delimitadores de palavras (e.g., pontuação e whitespace ou início/fim de linha).\nfoo* corresponde com qualquer palavra que começa foo.\n*foo* corresponde com qualquer palavra que inclui as 3 letras foo.";
|
||||
"notification_settings_always_notify" = "Sempre notificar";
|
||||
"notification_settings_never_notify" = "Nunca notificar";
|
||||
"notification_settings_word_to_match" = "palavra para corresponder";
|
||||
@@ -372,10 +372,10 @@
|
||||
"ssl_fingerprint_hash" = "Impressão digital (%@):";
|
||||
"ssl_could_not_verify" = "Não foi possível verificar identidade de servidor remoto.";
|
||||
"ssl_cert_not_trust" = "Isto pode significar que alguém está interceptando maliciosamente seu tráfico, ou que seu telefone não confia no certificado provido pelo servidor remoto.";
|
||||
"ssl_cert_new_account_expl" = "Se o/a administrador(a) do servidor tem dito que isto é esperado, assegure-se que a impressão digital abaixo bate com a impressão digital provida por ele(a).";
|
||||
"ssl_cert_new_account_expl" = "Se o/a administrador(a) do servidor tem dito que isto é esperado, assegure-se que a impressão digital abaixo corresponde com a impressão digital provida por ele(a).";
|
||||
"ssl_unexpected_existing_expl" = "O certificado tem mudado de um que esta confiado por seu telefone. Isto é ALTAMENTE INCOMUM. É recomendado que você NÃO ACEITE este novo certificado.";
|
||||
"ssl_expected_existing_expl" = "O certificado tem sido mudado de um previamente confiado para um que não é confiado. O servidor pode ter renovado o certificado dele. Contacte o/a administrador(a) do servidor a impressão digital esperada.";
|
||||
"ssl_only_accept" = "SOMENTE aceite o certificado se o/a administrador(a) do servidor tem publicado uma impressão digital que corresponde à acima.";
|
||||
"ssl_only_accept" = "SOMENTE aceite o certificado se o/a administrador(a) do servidor tem publicado uma impressão digital que corresponde com a acima.";
|
||||
"notice_encryption_enabled_ok" = "%@ ativou encriptação ponta-a-ponta.";
|
||||
"notice_encryption_enabled_unknown_algorithm" = "%1$@ ativou encriptação ponta-a-ponta (algoritmo não-reconhecido %2$@).";
|
||||
"device_details_rename_prompt_title" = "Nome da Sessão";
|
||||
@@ -468,7 +468,7 @@
|
||||
"attachment_large_with_resolution" = "Grande %@ (~%@)";
|
||||
"attachment_medium_with_resolution" = "Médio %@ (~%@)";
|
||||
"attachment_small_with_resolution" = "Pequeno %@ (~%@)";
|
||||
"attachment_size_prompt_message" = "Você pode desligar isto em configurações.";
|
||||
"attachment_size_prompt_message" = "Você pode desligar isto em ajustes.";
|
||||
"attachment_size_prompt_title" = "Confirmar tamanho para enviar";
|
||||
"room_displayname_all_other_participants_left" = "%@ (Saiu)";
|
||||
"auth_reset_password_error_not_found" = "Não encontrado";
|
||||
@@ -479,3 +479,4 @@
|
||||
"room_displayname_all_other_members_left" = "%@ (Saiu)";
|
||||
"attachment_unsupported_preview_message" = "Este tipo de arquivo não é suportado.";
|
||||
"attachment_unsupported_preview_title" = "Incapaz de previsualizar";
|
||||
"message_reply_to_sender_sent_their_location" = "tem compartilhado a localização dela(e).";
|
||||
|
||||
@@ -543,3 +543,7 @@
|
||||
"notice_feedback" = "Udalosť spätnej väzby (id: %@): %@";
|
||||
"resume_call" = "Pokračovať";
|
||||
"answer_call" = "Prijať hovor";
|
||||
"message_reply_to_sender_sent_their_location" = "zdieľal/a svoju polohu.";
|
||||
"account_link_email" = "Prepojený email";
|
||||
"account_linked_emails" = "Prepojené e-maily";
|
||||
"room_event_encryption_info_event_fingerprint_key" = "Deklarovaný kľúč odtlačkov prstov Ed25519\n";
|
||||
|
||||
@@ -478,3 +478,4 @@
|
||||
"attachment_unsupported_preview_message" = "Ky lloj kartele nuk mbulohet.";
|
||||
"attachment_unsupported_preview_title" = "S’arrihet të bëhet paraparje";
|
||||
"room_displayname_all_other_members_left" = "%@ (Iku)";
|
||||
"message_reply_to_sender_sent_their_location" = "ka dhënë vendndodhjen e vet.";
|
||||
|
||||
@@ -478,3 +478,4 @@
|
||||
"attachment_unsupported_preview_message" = "Den här filtypen stöds inte.";
|
||||
"attachment_unsupported_preview_title" = "Kunde inte förhandsgranska";
|
||||
"room_displayname_all_other_members_left" = "%@ (Kvar)";
|
||||
"message_reply_to_sender_sent_their_location" = "har delat sin plats.";
|
||||
|
||||
@@ -558,3 +558,4 @@
|
||||
"local_contacts_access_not_granted" = "Для пошуку користувачів серед локальних контактів потрібен доступ до ваших контактів, але %@ не має такого дозволу";
|
||||
"e2e_export_prompt" = "Це дає змогу експортувати в локальний файл ключі до повідомлень, отриманих вами в зашифрованих кімнатах. Тоді ви зможете імпортувати файл до іншого клієнта Matrix у майбутньому, і той клієнт також зможе розшифрувати ці повідомлення.\nЕкспортований файл дасть змогу всім, хто його прочитає, розшифрувати всі видимі вам зашифровані повідомлення.";
|
||||
"e2e_import_prompt" = "Це дає змогу імпортувати ключі шифрування, які ви раніше експортували з іншого клієнта Matrix. Тоді ви зможете розшифрувати всі повідомлення, які міг розшифрувати той клієнт.\nФайл експорту захищений парольною фразою. Введіть парольну фразу сюди, щоб розшифрувати файл.";
|
||||
"message_reply_to_sender_sent_their_location" = "надсилає дані про своє місцеперебування.";
|
||||
|
||||
@@ -193,8 +193,11 @@
|
||||
|
||||
/**
|
||||
Handle supported flows and associated information returned by the homeserver.
|
||||
@param authSession The session to be handled.
|
||||
@param fallbackSSOFlow A fallback SSO flow to be shown when the session has none
|
||||
e.g. A login SSO flow that can be shown for a registration session.
|
||||
*/
|
||||
- (void)handleAuthenticationSession:(MXAuthenticationSession *)authSession;
|
||||
- (void)handleAuthenticationSession:(MXAuthenticationSession *)authSession withFallbackSSOFlow:(MXLoginSSOFlow *)fallbackSSOFlow;
|
||||
|
||||
/**
|
||||
Customize the MXHTTPClientOnUnrecognizedCertificate block that will be used to handle unrecognized certificate observed during authentication challenge from a server.
|
||||
@@ -219,6 +222,11 @@
|
||||
*/
|
||||
- (void)testUserRegistration:(void (^)(MXError *mxError))callback;
|
||||
|
||||
/**
|
||||
Searches an array of `MXLoginFlow` returning the first valid `MXLoginSSOFlow` found.
|
||||
*/
|
||||
- (MXLoginSSOFlow*)loginSSOFlowWithProvidersFromFlows:(NSArray<MXLoginFlow*>*)loginFlows;
|
||||
|
||||
/**
|
||||
Action registered on the following events:
|
||||
- 'UIControlEventTouchUpInside' for each UIButton instance.
|
||||
|
||||
@@ -621,41 +621,51 @@
|
||||
// Reset potential authentication fallback url
|
||||
authenticationFallback = nil;
|
||||
|
||||
if (mxRestClient)
|
||||
if (mxRestClient && (self.authType == MXKAuthenticationTypeLogin || self.authType == MXKAuthenticationTypeRegister))
|
||||
{
|
||||
if (_authType == MXKAuthenticationTypeLogin)
|
||||
{
|
||||
mxCurrentOperation = [mxRestClient getLoginSession:^(MXAuthenticationSession* authSession) {
|
||||
|
||||
[self handleAuthenticationSession:authSession];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
[self onFailureDuringMXOperation:error];
|
||||
|
||||
}];
|
||||
}
|
||||
else if (_authType == MXKAuthenticationTypeRegister)
|
||||
{
|
||||
mxCurrentOperation = [mxRestClient getRegisterSession:^(MXAuthenticationSession* authSession){
|
||||
|
||||
[self handleAuthenticationSession:authSession];
|
||||
|
||||
} failure:^(NSError *error){
|
||||
|
||||
[self onFailureDuringMXOperation:error];
|
||||
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not supported for other types
|
||||
MXLogDebug(@"[MXKAuthenticationVC] refreshAuthenticationSession is ignored");
|
||||
}
|
||||
MXWeakify(self);
|
||||
|
||||
// Get the login session to determine available SSO flows.
|
||||
mxCurrentOperation = [mxRestClient getLoginSession:^(MXAuthenticationSession* loginAuthSession) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
if (self.authType == MXKAuthenticationTypeRegister)
|
||||
{
|
||||
MXWeakify(self);
|
||||
self->mxCurrentOperation = [self->mxRestClient getRegisterSession:^(MXAuthenticationSession* registerAuthSession) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
// Handle the register session along with any SSO flows from the login session
|
||||
MXLoginSSOFlow *loginSSOFlow = [self loginSSOFlowWithProvidersFromFlows:loginAuthSession.flows];
|
||||
[self handleAuthenticationSession:registerAuthSession withFallbackSSOFlow:loginSSOFlow];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
[self onFailureDuringMXOperation:error];
|
||||
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle the login session by itself
|
||||
[self handleAuthenticationSession:loginAuthSession withFallbackSSOFlow:nil];
|
||||
}
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
[self onFailureDuringMXOperation:error];
|
||||
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Not supported for other types
|
||||
MXLogDebug(@"[MXKAuthenticationVC] refreshAuthenticationSession is ignored");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)handleAuthenticationSession:(MXAuthenticationSession *)authSession
|
||||
- (void)handleAuthenticationSession:(MXAuthenticationSession *)authSession withFallbackSSOFlow:(MXLoginSSOFlow *)fallbackSSOFlow
|
||||
{
|
||||
mxCurrentOperation = nil;
|
||||
|
||||
@@ -901,6 +911,27 @@
|
||||
mxCurrentOperation = [mxRestClient testUserRegistration:self.authInputsView.userId callback:callback];
|
||||
}
|
||||
|
||||
- (MXLoginSSOFlow*)loginSSOFlowWithProvidersFromFlows:(NSArray<MXLoginFlow*>*)loginFlows
|
||||
{
|
||||
MXLoginSSOFlow *ssoFlowWithProviders;
|
||||
|
||||
for (MXLoginFlow *loginFlow in loginFlows)
|
||||
{
|
||||
if ([loginFlow isKindOfClass:MXLoginSSOFlow.class])
|
||||
{
|
||||
MXLoginSSOFlow *ssoFlow = (MXLoginSSOFlow *)loginFlow;
|
||||
|
||||
if (ssoFlow.identityProviders.count)
|
||||
{
|
||||
ssoFlowWithProviders = ssoFlow;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ssoFlowWithProviders;
|
||||
}
|
||||
|
||||
- (IBAction)onButtonPressed:(id)sender
|
||||
{
|
||||
[self dismissKeyboard];
|
||||
@@ -1451,7 +1482,9 @@
|
||||
|
||||
MXRestClient *mxRestClient = [[MXRestClient alloc] initWithCredentials:credentials andOnUnrecognizedCertificateBlock:^BOOL(NSData *certificate) {
|
||||
return NO;
|
||||
}];
|
||||
} andPersistentTokenDataHandler:^(void (^handler)(NSArray<MXCredentials *> *credentials, void (^completion)(BOOL didUpdateCredentials))) {
|
||||
[[MXKAccountManager sharedManager] readAndWriteCredentials:handler];
|
||||
} andUnauthenticatedHandler: nil];
|
||||
|
||||
MXWeakify(self);
|
||||
[[MXKAccountManager sharedManager].dehydrationService rehydrateDeviceWithMatrixRestClient:mxRestClient dehydrationKey:keyData success:^(NSString * deviceId) {
|
||||
|
||||
@@ -1197,7 +1197,7 @@ static const CGFloat kLocalPreviewMargin = 20;
|
||||
if (roomListener && mxCall.room)
|
||||
{
|
||||
MXWeakify(self);
|
||||
[mxCall.room liveTimeline:^(MXEventTimeline *liveTimeline) {
|
||||
[mxCall.room liveTimeline:^(id<MXEventTimeline> liveTimeline) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[liveTimeline removeListener:self->roomListener];
|
||||
|
||||
@@ -117,7 +117,7 @@ typedef enum : NSUInteger
|
||||
*/
|
||||
@property (nonatomic, readonly) MXRoomMember *mxRoomMember;
|
||||
@property (nonatomic, readonly) MXRoom *mxRoom;
|
||||
@property (nonatomic, readonly) MXEventTimeline *mxRoomLiveTimeline;
|
||||
@property (nonatomic, readonly) id<MXEventTimeline> mxRoomLiveTimeline;
|
||||
|
||||
/**
|
||||
Enable mention option. NO by default
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
id roomDidFlushDataNotificationObserver;
|
||||
|
||||
// Cache for the room live timeline
|
||||
MXEventTimeline *mxRoomLiveTimeline;
|
||||
id<MXEventTimeline> mxRoomLiveTimeline;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -134,7 +134,7 @@
|
||||
mxRoom = room;
|
||||
|
||||
MXWeakify(self);
|
||||
[mxRoom liveTimeline:^(MXEventTimeline *liveTimeline) {
|
||||
[mxRoom liveTimeline:^(id<MXEventTimeline> liveTimeline) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
self->mxRoomLiveTimeline = liveTimeline;
|
||||
@@ -152,7 +152,7 @@
|
||||
}];
|
||||
}
|
||||
|
||||
- (MXEventTimeline *)mxRoomLiveTimeline
|
||||
- (id<MXEventTimeline> )mxRoomLiveTimeline
|
||||
{
|
||||
// @TODO(async-state): Just here for dev
|
||||
NSAssert(mxRoomLiveTimeline, @"[MXKRoomMemberDetailsViewController] Room live timeline must be preloaded before accessing to MXKRoomMemberDetailsViewController.mxRoomLiveTimeline");
|
||||
@@ -569,7 +569,7 @@
|
||||
if (membersListener && mxRoom)
|
||||
{
|
||||
MXWeakify(self);
|
||||
[mxRoom liveTimeline:^(MXEventTimeline *liveTimeline) {
|
||||
[mxRoom liveTimeline:^(id<MXEventTimeline> liveTimeline) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[liveTimeline removeListener:self->membersListener];
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
if (roomListener)
|
||||
{
|
||||
MXWeakify(self);
|
||||
[mxRoom liveTimeline:^(MXEventTimeline *liveTimeline) {
|
||||
[mxRoom liveTimeline:^(id<MXEventTimeline> liveTimeline) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[liveTimeline removeListener:self->roomListener];
|
||||
@@ -139,7 +139,7 @@
|
||||
{
|
||||
// Register a listener to handle messages related to room name, topic...
|
||||
MXWeakify(self);
|
||||
[mxRoom liveTimeline:^(MXEventTimeline *liveTimeline) {
|
||||
[mxRoom liveTimeline:^(id<MXEventTimeline> liveTimeline) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
self->roomListener = [liveTimeline listenToEventsOfTypes:@[kMXEventTypeStringRoomName, kMXEventTypeStringRoomTopic, kMXEventTypeStringRoomAliases, kMXEventTypeStringRoomAvatar, kMXEventTypeStringRoomPowerLevels, kMXEventTypeStringRoomCanonicalAlias, kMXEventTypeStringRoomJoinRules, kMXEventTypeStringRoomGuestAccess, kMXEventTypeStringRoomHistoryVisibility] onEvent:^(MXEvent *event, MXTimelineDirection direction, MXRoomState *roomState) {
|
||||
|
||||
@@ -1,440 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2019 The Matrix.org Foundation C.I.C
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import <MatrixSDK/MatrixSDK.h>
|
||||
|
||||
#import "MXKViewController.h"
|
||||
#import "MXKRoomDataSource.h"
|
||||
#import "MXKRoomTitleView.h"
|
||||
#import "MXKRoomInputToolbarView.h"
|
||||
#import "MXKRoomActivitiesView.h"
|
||||
#import "MXKEventDetailsView.h"
|
||||
|
||||
#import "MXKAttachmentsViewController.h"
|
||||
#import "MXKAttachmentAnimator.h"
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MXKRoomViewControllerJoinRoomResult) {
|
||||
MXKRoomViewControllerJoinRoomResultSuccess,
|
||||
MXKRoomViewControllerJoinRoomResultFailureRoomEmpty,
|
||||
MXKRoomViewControllerJoinRoomResultFailureJoinInProgress,
|
||||
MXKRoomViewControllerJoinRoomResultFailureGeneric
|
||||
};
|
||||
|
||||
/**
|
||||
This view controller displays messages of a room. Only one matrix session is handled by this view controller.
|
||||
*/
|
||||
@interface MXKRoomViewController : MXKViewController <MXKDataSourceDelegate, MXKRoomTitleViewDelegate, MXKRoomInputToolbarViewDelegate, UITableViewDelegate, UIDocumentInteractionControllerDelegate, MXKAttachmentsViewControllerDelegate, MXKRoomActivitiesViewDelegate, MXKSourceAttachmentAnimatorDelegate>
|
||||
{
|
||||
@protected
|
||||
/**
|
||||
The identifier of the current event displayed at the bottom of the table (just above the toolbar).
|
||||
Use to anchor the message displayed at the bottom during table refresh.
|
||||
*/
|
||||
NSString *currentEventIdAtTableBottom;
|
||||
|
||||
/**
|
||||
Boolean value used to scroll to bottom the bubble history after refresh.
|
||||
*/
|
||||
BOOL shouldScrollToBottomOnTableRefresh;
|
||||
|
||||
/**
|
||||
Potential event details view.
|
||||
*/
|
||||
__weak MXKEventDetailsView *eventDetailsView;
|
||||
|
||||
/**
|
||||
Current alert (if any).
|
||||
*/
|
||||
__weak UIAlertController *currentAlert;
|
||||
|
||||
/**
|
||||
The document interaction Controller used to share attachment
|
||||
*/
|
||||
UIDocumentInteractionController *documentInteractionController;
|
||||
|
||||
/**
|
||||
The current shared attachment.
|
||||
*/
|
||||
MXKAttachment *currentSharedAttachment;
|
||||
|
||||
/**
|
||||
The potential text input placeholder is saved when it is replaced temporarily
|
||||
*/
|
||||
NSString *savedInputToolbarPlaceholder;
|
||||
|
||||
/**
|
||||
Tell whether the input toolbar required to run an animation indicator.
|
||||
*/
|
||||
BOOL isInputToolbarProcessing;
|
||||
|
||||
/**
|
||||
Tell whether a device rotation is in progress
|
||||
*/
|
||||
BOOL isSizeTransitionInProgress;
|
||||
|
||||
/**
|
||||
The current visibility of the status bar in this view controller.
|
||||
*/
|
||||
BOOL isStatusBarHidden;
|
||||
|
||||
/**
|
||||
YES to prevent `bubblesTableView` scrolling when calling -[setBubbleTableViewContentOffset:animated:]
|
||||
*/
|
||||
BOOL preventBubblesTableViewScroll;
|
||||
}
|
||||
|
||||
/**
|
||||
The current data source associated to the view controller.
|
||||
*/
|
||||
@property (nonatomic, readonly) MXKRoomDataSource *roomDataSource;
|
||||
|
||||
/**
|
||||
Flag indicating if this instance has the memory ownership of its `roomDataSource`.
|
||||
If YES, it will release it on [self destroy] call;
|
||||
Default is NO.
|
||||
*/
|
||||
@property (nonatomic) BOOL hasRoomDataSourceOwnership;
|
||||
|
||||
/**
|
||||
Tell whether the bubbles table view display is in transition. Its display is not warranty during the transition.
|
||||
*/
|
||||
@property (nonatomic, getter=isBubbleTableViewDisplayInTransition) BOOL bubbleTableViewDisplayInTransition;
|
||||
|
||||
/**
|
||||
Tell whether the automatic events acknowledgement (based on read receipt) is enabled.
|
||||
Default is YES.
|
||||
*/
|
||||
@property (nonatomic, getter=isEventsAcknowledgementEnabled) BOOL eventsAcknowledgementEnabled;
|
||||
|
||||
/**
|
||||
Tell whether the room read marker must be updated when an event is acknowledged with a read receipt.
|
||||
Default is NO.
|
||||
*/
|
||||
@property (nonatomic) BOOL updateRoomReadMarker;
|
||||
|
||||
/**
|
||||
When the room view controller displays a room data source based on a timeline with an initial event,
|
||||
the bubble table view content is scrolled by default to display the top of this event at the center of the screen
|
||||
the first time it appears.
|
||||
Use this property to force the table view to center its content on the bottom part of the event.
|
||||
Default is NO.
|
||||
*/
|
||||
@property (nonatomic) BOOL centerBubblesTableViewContentOnTheInitialEventBottom;
|
||||
|
||||
/**
|
||||
The current title view defined into the view controller.
|
||||
*/
|
||||
@property (nonatomic, weak, readonly) MXKRoomTitleView* titleView;
|
||||
|
||||
/**
|
||||
The current input toolbar view defined into the view controller.
|
||||
*/
|
||||
@property (nonatomic, weak, readonly) MXKRoomInputToolbarView* inputToolbarView;
|
||||
|
||||
/**
|
||||
The current extra info view defined into the view controller.
|
||||
*/
|
||||
@property (nonatomic, readonly) MXKRoomActivitiesView* activitiesView;
|
||||
|
||||
/**
|
||||
The threshold used to trigger inconspicuous back pagination, or forwards pagination
|
||||
for non live timeline. A pagination is triggered when the vertical content offset
|
||||
is lower this threshold.
|
||||
Default is 300.
|
||||
*/
|
||||
@property (nonatomic) NSUInteger paginationThreshold;
|
||||
|
||||
/**
|
||||
The maximum number of messages to retrieve during a pagination. Default is 30.
|
||||
*/
|
||||
@property (nonatomic) NSUInteger paginationLimit;
|
||||
|
||||
/**
|
||||
Enable/disable saving of the current typed text in message composer when view disappears.
|
||||
The message composer is prefilled with this text when the room is opened again.
|
||||
This property value is YES by default.
|
||||
*/
|
||||
@property BOOL saveProgressTextInput;
|
||||
|
||||
/**
|
||||
The invited rooms can be automatically joined when the data source is ready.
|
||||
This property enable/disable this option. Its value is YES by default.
|
||||
*/
|
||||
@property BOOL autoJoinInvitedRoom;
|
||||
|
||||
/**
|
||||
Tell whether the room history is automatically scrolled to the most recent messages
|
||||
when a keyboard is presented. YES by default.
|
||||
This option is ignored when an alert is presented.
|
||||
*/
|
||||
@property BOOL scrollHistoryToTheBottomOnKeyboardPresentation;
|
||||
|
||||
/**
|
||||
YES (default) to show actions button in document preview. NO otherwise.
|
||||
*/
|
||||
@property BOOL allowActionsInDocumentPreview;
|
||||
|
||||
/**
|
||||
Duration of the animation in case of the composer needs to be resized (default 0.3s)
|
||||
*/
|
||||
@property NSTimeInterval resizeComposerAnimationDuration;
|
||||
|
||||
/**
|
||||
This object is defined when the displayed room is left. It is added into the bubbles table header.
|
||||
This label is used to display the reason why the room has been left.
|
||||
*/
|
||||
@property (nonatomic, weak, readonly) UILabel *leftRoomReasonLabel;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UITableView *bubblesTableView;
|
||||
@property (weak, nonatomic) IBOutlet UIView *roomTitleViewContainer;
|
||||
@property (weak, nonatomic) IBOutlet UIView *roomInputToolbarContainer;
|
||||
@property (weak, nonatomic) IBOutlet UIView *roomActivitiesContainer;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bubblesTableViewTopConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bubblesTableViewBottomConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *roomActivitiesContainerHeightConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *roomInputToolbarContainerHeightConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *roomInputToolbarContainerBottomConstraint;
|
||||
|
||||
#pragma mark - Class methods
|
||||
|
||||
/**
|
||||
Returns the `UINib` object initialized for a `MXKRoomViewController`.
|
||||
|
||||
@return The initialized `UINib` object or `nil` if there were errors during initialization
|
||||
or the nib file could not be located.
|
||||
|
||||
@discussion You may override this method to provide a customized nib. If you do,
|
||||
you should also override `roomViewController` to return your
|
||||
view controller loaded from your custom nib.
|
||||
*/
|
||||
+ (UINib *)nib;
|
||||
|
||||
/**
|
||||
Creates and returns a new `MXKRoomViewController` object.
|
||||
|
||||
@discussion This is the designated initializer for programmatic instantiation.
|
||||
@return An initialized `MXKRoomViewController` object if successful, `nil` otherwise.
|
||||
*/
|
||||
+ (instancetype)roomViewController;
|
||||
|
||||
/**
|
||||
Display a room.
|
||||
|
||||
@param dataSource the data source .
|
||||
*/
|
||||
- (void)displayRoom:(MXKRoomDataSource*)dataSource;
|
||||
|
||||
/**
|
||||
This method is called when the associated data source is ready.
|
||||
|
||||
By default this operation triggers the initial back pagination when the user is an actual
|
||||
member of the room (membership = join).
|
||||
|
||||
The invited rooms are automatically joined during this operation if 'autoJoinInvitedRoom' is YES.
|
||||
When the room is successfully joined, an initial back pagination is triggered too.
|
||||
Else nothing is done for the invited rooms.
|
||||
|
||||
Override it to customize the view controller behavior when the data source is ready.
|
||||
*/
|
||||
- (void)onRoomDataSourceReady;
|
||||
|
||||
/**
|
||||
Update view controller appearance according to the state of its associated data source.
|
||||
This method is called in the following use cases:
|
||||
- on data source change (see `[MXKRoomViewController displayRoom:]`).
|
||||
- on data source state change (see `[MXKDataSourceDelegate dataSource:didStateChange:]`)
|
||||
- when view did appear.
|
||||
|
||||
The default implementation:
|
||||
- show input toolbar view if the dataSource is defined and ready (`MXKDataSourceStateReady`), hide toolbar in others use cases.
|
||||
- stop activity indicator if the dataSource is defined and ready (`MXKDataSourceStateReady`).
|
||||
- update view controller title with room information.
|
||||
|
||||
Override it to customize view appearance according to data source state.
|
||||
*/
|
||||
- (void)updateViewControllerAppearanceOnRoomDataSourceState;
|
||||
|
||||
/**
|
||||
This method is called when the associated data source has encountered an error on the timeline.
|
||||
|
||||
Override it to customize the view controller behavior.
|
||||
|
||||
@param notif the notification data sent with kMXKRoomDataSourceTimelineError notif.
|
||||
*/
|
||||
- (void)onTimelineError:(NSNotification *)notif;
|
||||
|
||||
/**
|
||||
Join the current displayed room.
|
||||
|
||||
This operation fails if the user has already joined the room, or if the data source is not ready.
|
||||
It fails if a join request is already running too.
|
||||
|
||||
@param completion the block to execute at the end of the operation.
|
||||
You may specify nil for this parameter.
|
||||
*/
|
||||
- (void)joinRoom:(void(^)(MXKRoomViewControllerJoinRoomResult result))completion;
|
||||
|
||||
/**
|
||||
Join a room with a room id or an alias.
|
||||
|
||||
This operation fails if the user has already joined the room, or if the data source is not ready,
|
||||
or if the access to the room is forbidden to the user.
|
||||
It fails if a join request is already running too.
|
||||
|
||||
@param roomIdOrAlias the id or the alias of the room to join.
|
||||
@param viaServers The server names to try and join through in addition to those that are automatically chosen. It is optional and can be nil.
|
||||
@param signUrl the signurl paramater passed with a 3PID invitation. It is optional and can be nil.
|
||||
|
||||
@param completion the block to execute at the end of the operation.
|
||||
You may specify nil for this parameter.
|
||||
*/
|
||||
- (void)joinRoomWithRoomIdOrAlias:(NSString*)roomIdOrAlias
|
||||
viaServers:(NSArray<NSString*>*)viaServers
|
||||
andSignUrl:(NSString*)signUrl
|
||||
completion:(void(^)(MXKRoomViewControllerJoinRoomResult result))completion;
|
||||
|
||||
/**
|
||||
Update view controller appearance when the user is about to leave the displayed room.
|
||||
This method is called when the user will leave the current room (see `kMXSessionWillLeaveRoomNotification`).
|
||||
|
||||
The default implementation:
|
||||
- discard `roomDataSource`
|
||||
- hide input toolbar view
|
||||
- freeze the room title display
|
||||
- add a label (`leftRoomReasonLabel`) in bubbles table header to display the reason why the room has been left.
|
||||
|
||||
Override it to customize view appearance, or to withdraw the view controller.
|
||||
|
||||
@param event the MXEvent responsible for the leaving.
|
||||
*/
|
||||
- (void)leaveRoomOnEvent:(MXEvent*)event;
|
||||
|
||||
/**
|
||||
Register the class used to instantiate the title view which will handle the room name display.
|
||||
|
||||
The resulting view is added into 'roomTitleViewContainer' view, which must be defined before calling this method.
|
||||
|
||||
Note: By default the room name is displayed by using 'navigationItem.title' field of the view controller.
|
||||
|
||||
@param roomTitleViewClass a MXKRoomTitleView-inherited class.
|
||||
*/
|
||||
- (void)setRoomTitleViewClass:(Class)roomTitleViewClass;
|
||||
|
||||
/**
|
||||
Register the class used to instantiate the input toolbar view which will handle message composer
|
||||
and attachments selection for the room.
|
||||
|
||||
The resulting view is added into 'roomInputToolbarContainer' view, which must be defined before calling this method.
|
||||
|
||||
@param roomInputToolbarViewClass a MXKRoomInputToolbarView-inherited class, or nil to remove the current view.
|
||||
*/
|
||||
- (void)setRoomInputToolbarViewClass:(Class)roomInputToolbarViewClass;
|
||||
|
||||
/**
|
||||
Register the class used to instantiate the extra info view.
|
||||
|
||||
The resulting view is added into 'roomActivitiesContainer' view, which must be defined before calling this method.
|
||||
|
||||
@param roomActivitiesViewClass a MXKRoomActivitiesViewClass-inherited class, or nil to remove the current view.
|
||||
*/
|
||||
- (void)setRoomActivitiesViewClass:(Class)roomActivitiesViewClass;
|
||||
|
||||
/**
|
||||
Register the class used to instantiate the viewer dedicated to the attachments with thumbnail.
|
||||
By default 'MXKAttachmentsViewController' class is used.
|
||||
|
||||
@param attachmentsViewerClass a MXKAttachmentsViewController-inherited class, or nil to restore the default class.
|
||||
*/
|
||||
- (void)setAttachmentsViewerClass:(Class)attachmentsViewerClass;
|
||||
|
||||
/**
|
||||
Register the view class used to display the details of an event.
|
||||
MXKEventDetailsView is used by default.
|
||||
|
||||
@param eventDetailsViewClass a MXKEventDetailsView-inherited class.
|
||||
*/
|
||||
- (void)setEventDetailsViewClass:(Class)eventDetailsViewClass;
|
||||
|
||||
/**
|
||||
Detect and process potential IRC command in provided string.
|
||||
|
||||
@param string to analyse
|
||||
@return YES if IRC style command has been detected and interpreted.
|
||||
*/
|
||||
- (BOOL)isIRCStyleCommand:(NSString*)string;
|
||||
|
||||
/**
|
||||
Mention the member display name in the current text of the message composer.
|
||||
The message composer becomes then the first responder.
|
||||
*/
|
||||
- (void)mention:(MXRoomMember*)roomMember;
|
||||
|
||||
/**
|
||||
Force to dismiss keyboard if any
|
||||
*/
|
||||
- (void)dismissKeyboard;
|
||||
|
||||
/**
|
||||
Tell whether the most recent message of the room history is visible.
|
||||
*/
|
||||
- (BOOL)isBubblesTableScrollViewAtTheBottom;
|
||||
|
||||
/**
|
||||
Scroll the room history until the most recent message.
|
||||
*/
|
||||
- (void)scrollBubblesTableViewToBottomAnimated:(BOOL)animated;
|
||||
|
||||
/**
|
||||
Dismiss the keyboard and all the potential subviews.
|
||||
*/
|
||||
- (void)dismissTemporarySubViews;
|
||||
|
||||
/**
|
||||
Display a popup with the event detais.
|
||||
|
||||
@param event the event to inspect.
|
||||
*/
|
||||
- (void)showEventDetails:(MXEvent *)event;
|
||||
|
||||
/**
|
||||
Present the attachments viewer by displaying the attachment of the provided cell.
|
||||
|
||||
@param cell the table view cell with attachment
|
||||
*/
|
||||
- (void)showAttachmentInCell:(UITableViewCell*)cell;
|
||||
|
||||
/**
|
||||
Force a refresh of the room history display.
|
||||
|
||||
You should not call this method directly.
|
||||
You may override it in inherited 'MXKRoomViewController' class.
|
||||
|
||||
@param useBottomAnchor tells whether the updated history must keep display the same event at the bottom.
|
||||
@return a boolean value which tells whether the table has been scrolled to the bottom.
|
||||
*/
|
||||
- (BOOL)reloadBubblesTable:(BOOL)useBottomAnchor;
|
||||
|
||||
/**
|
||||
Sets the offset from the content `bubblesTableView`'s origin. Take into account `preventBubblesTableViewScroll` value.
|
||||
|
||||
@param contentOffset Offset from the content `bubblesTableView`’s origin.
|
||||
@param animated YES to animate the transition.
|
||||
*/
|
||||
- (void)setBubbleTableViewContentOffset:(CGPoint)contentOffset animated:(BOOL)animated;
|
||||
|
||||
@end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,64 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MXKRoomViewController">
|
||||
<connections>
|
||||
<outlet property="bubblesTableView" destination="BGD-sd-SQR" id="OG4-Tw-Ovt"/>
|
||||
<outlet property="bubblesTableViewBottomConstraint" destination="Ksk-39-kfi" id="CTo-Ux-4NP"/>
|
||||
<outlet property="bubblesTableViewTopConstraint" destination="X14-4s-uGM" id="Hic-6h-N05"/>
|
||||
<outlet property="roomActivitiesContainer" destination="XX4-n6-hCm" id="uD0-ab-8s8"/>
|
||||
<outlet property="roomActivitiesContainerHeightConstraint" destination="E8v-l2-8eV" id="ebD-oV-ttx"/>
|
||||
<outlet property="roomInputToolbarContainer" destination="nLd-BP-JAE" id="1dp-P1-0js"/>
|
||||
<outlet property="roomInputToolbarContainerBottomConstraint" destination="kQ6-Cg-FMi" id="nHr-fR-XnV"/>
|
||||
<outlet property="roomInputToolbarContainerHeightConstraint" destination="5eD-Fm-RDb" id="6ny-5w-1UA"/>
|
||||
<outlet property="view" destination="iN0-l3-epB" id="ieV-u7-rXU"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" keyboardDismissMode="interactive" style="plain" separatorStyle="none" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" translatesAutoresizingMaskIntoConstraints="NO" id="BGD-sd-SQR">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="626"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</tableView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XX4-n6-hCm" userLabel="Activities Container">
|
||||
<rect key="frame" x="0.0" y="606" width="375" height="20"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="20" id="E8v-l2-8eV"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nLd-BP-JAE" userLabel="Room Input Toolbar Container">
|
||||
<rect key="frame" x="0.0" y="626" width="375" height="41"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="41" id="5eD-Fm-RDb"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="BGD-sd-SQR" secondAttribute="trailing" id="0la-ok-MBr"/>
|
||||
<constraint firstItem="nLd-BP-JAE" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="4Q7-hr-rqi"/>
|
||||
<constraint firstAttribute="bottom" secondItem="BGD-sd-SQR" secondAttribute="bottom" constant="41" id="Ksk-39-kfi"/>
|
||||
<constraint firstItem="XX4-n6-hCm" firstAttribute="bottom" secondItem="nLd-BP-JAE" secondAttribute="top" id="QO8-nF-xys"/>
|
||||
<constraint firstItem="XX4-n6-hCm" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" id="WhE-lH-ZtR"/>
|
||||
<constraint firstItem="BGD-sd-SQR" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="X14-4s-uGM"/>
|
||||
<constraint firstAttribute="trailing" secondItem="nLd-BP-JAE" secondAttribute="trailing" id="YAu-gd-ItG"/>
|
||||
<constraint firstItem="XX4-n6-hCm" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="csl-KT-4s9"/>
|
||||
<constraint firstItem="BGD-sd-SQR" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="haP-Kv-OLI"/>
|
||||
<constraint firstAttribute="bottom" secondItem="nLd-BP-JAE" secondAttribute="bottom" id="kQ6-Cg-FMi"/>
|
||||
</constraints>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -14,3 +14,4 @@
|
||||
|
||||
#import "MXKRoomInputToolbarView.h"
|
||||
#import "MXKImageView.h"
|
||||
#import "MXKRoomBubbleCellData.h"
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#import <MatrixSDK/MatrixSDK.h>
|
||||
#import "MXKAccountData.h"
|
||||
|
||||
@class MXKAccount;
|
||||
|
||||
@@ -56,29 +57,7 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
|
||||
`MXKAccount` object contains the credentials of a logged matrix user. It is used to handle matrix
|
||||
session and presence for this user.
|
||||
*/
|
||||
@interface MXKAccount : NSObject <NSCoding>
|
||||
|
||||
/**
|
||||
The account's credentials: homeserver, access token, user id.
|
||||
*/
|
||||
@property (nonatomic, readonly) MXCredentials *mxCredentials;
|
||||
|
||||
/**
|
||||
The identity server URL.
|
||||
*/
|
||||
@property (nonatomic) NSString *identityServerURL;
|
||||
|
||||
/**
|
||||
The antivirus server URL, if any (nil by default).
|
||||
Set a non-null url to configure the antivirus scanner use.
|
||||
*/
|
||||
@property (nonatomic) NSString *antivirusServerURL;
|
||||
|
||||
/**
|
||||
The Push Gateway URL used to send event notifications to (nil by default).
|
||||
This URL should be over HTTPS and never over HTTP.
|
||||
*/
|
||||
@property (nonatomic) NSString *pushGatewayURL;
|
||||
@interface MXKAccount : MXKAccountData
|
||||
|
||||
/**
|
||||
The matrix REST client used to make matrix API requests.
|
||||
@@ -107,12 +86,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
|
||||
*/
|
||||
@property (nonatomic, readonly) NSString *fullDisplayName;
|
||||
|
||||
/**
|
||||
The 3PIDs linked to this account.
|
||||
[self load3PIDs] must be called to update the property.
|
||||
*/
|
||||
@property (nonatomic, readonly) NSArray<MXThirdPartyIdentifier *> *threePIDs;
|
||||
|
||||
/**
|
||||
The email addresses linked to this account.
|
||||
This is a subset of self.threePIDs.
|
||||
@@ -125,12 +98,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
|
||||
*/
|
||||
@property (nonatomic, readonly) NSArray<NSString *> *linkedPhoneNumbers;
|
||||
|
||||
/**
|
||||
The account user's device.
|
||||
[self loadDeviceInformation] must be called to update the property.
|
||||
*/
|
||||
@property (nonatomic, readonly) MXDevice *device;
|
||||
|
||||
/**
|
||||
The account user's presence (`MXPresenceUnknown` by default, available if matrix session `mxSession` is opened).
|
||||
The notification `kMXKAccountUserInfoDidChangeNotification` is posted in case of change of this property.
|
||||
@@ -148,11 +115,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL pushNotificationServiceIsActive;
|
||||
|
||||
/**
|
||||
Transient information storage.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly) NSMutableDictionary<NSString *, id<NSCoding>> *others;
|
||||
|
||||
/**
|
||||
Enable Push notification based on Apple Push Notification Service (APNS).
|
||||
|
||||
@@ -166,11 +128,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
|
||||
success:(void (^)(void))success
|
||||
failure:(void (^)(NSError *))failure;
|
||||
|
||||
/**
|
||||
Flag to indicate that an APNS pusher has been set on the homeserver for this device.
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL hasPusherForPushNotifications;
|
||||
|
||||
/**
|
||||
The Push notification activity (based on PushKit) for this account.
|
||||
YES when Push is turned on (locally available and enabled homeserver side).
|
||||
@@ -190,26 +147,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
|
||||
success:(void (^)(void))success
|
||||
failure:(void (^)(NSError *))failure;
|
||||
|
||||
/**
|
||||
Flag to indicate that a PushKit pusher has been set on the homeserver for this device.
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL hasPusherForPushKitNotifications;
|
||||
|
||||
|
||||
/**
|
||||
Enable In-App notifications based on Remote notifications rules.
|
||||
NO by default.
|
||||
*/
|
||||
@property (nonatomic) BOOL enableInAppNotifications;
|
||||
|
||||
/**
|
||||
Disable the account without logging out (NO by default).
|
||||
|
||||
A matrix session is automatically opened for the account when this property is toggled from YES to NO.
|
||||
The session is closed when this property is set to YES.
|
||||
*/
|
||||
@property (nonatomic,getter=isDisabled) BOOL disabled;
|
||||
|
||||
/**
|
||||
Manage the online presence event.
|
||||
|
||||
@@ -217,11 +154,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
|
||||
*/
|
||||
@property (nonatomic) BOOL hideUserPresence;
|
||||
|
||||
/**
|
||||
Flag indicating if the end user has been warned about encryption and its limitations.
|
||||
*/
|
||||
@property (nonatomic,getter=isWarnedAboutEncryption) BOOL warnedAboutEncryption;
|
||||
|
||||
/**
|
||||
Register the MXKAccountOnCertificateChange block that will be used to handle certificate change during account use.
|
||||
This block is nil by default, any new certificate is ignored/untrusted (this will abort the connection to the server).
|
||||
@@ -284,11 +216,6 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
|
||||
|
||||
#pragma mark - Soft logout
|
||||
|
||||
/**
|
||||
Flag to indicate if the account has been logged out by the homeserver admin.
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL isSoftLogout;
|
||||
|
||||
/**
|
||||
Soft logout the account.
|
||||
|
||||
@@ -432,4 +359,8 @@ typedef BOOL (^MXKAccountOnCertificateChange)(MXKAccount *mxAccount, NSData *cer
|
||||
success:(void (^)(void))success
|
||||
failure:(void (^)(NSError *error))failure;
|
||||
|
||||
/**
|
||||
Handle unauthenticated errors from the server triggering hard/soft logouts as appropriate.
|
||||
*/
|
||||
- (void)handleUnauthenticatedWithError:(MXError *)error isSoftLogout:(BOOL)isSoftLogout isRefreshTokenAuth:(BOOL)isRefreshTokenAuth andCompletion:(void (^)(void))completion;
|
||||
@end
|
||||
|
||||
@@ -36,6 +36,8 @@
|
||||
|
||||
#import "MXKSwiftHeader.h"
|
||||
|
||||
#import "GeneratedInterface-Swift.h"
|
||||
|
||||
NSString *const kMXKAccountUserInfoDidChangeNotification = @"kMXKAccountUserInfoDidChangeNotification";
|
||||
NSString *const kMXKAccountAPNSActivityDidChangeNotification = @"kMXKAccountAPNSActivityDidChangeNotification";
|
||||
NSString *const kMXKAccountPushKitActivityDidChangeNotification = @"kMXKAccountPushKitActivityDidChangeNotification";
|
||||
@@ -92,13 +94,10 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
@property (nonatomic, strong) id<MXBackgroundTask> backgroundTask;
|
||||
@property (nonatomic, strong) id<MXBackgroundTask> backgroundSyncBgTask;
|
||||
|
||||
@property (nonatomic, strong) NSMutableDictionary<NSString *, id<NSCoding>> *others;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MXKAccount
|
||||
@synthesize mxCredentials, mxSession, mxRestClient;
|
||||
@synthesize threePIDs;
|
||||
@synthesize mxSession, mxRestClient;
|
||||
@synthesize userPresence;
|
||||
@synthesize userTintColor;
|
||||
@synthesize hideUserPresence;
|
||||
@@ -144,7 +143,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
notifyOpenSessionFailure = YES;
|
||||
|
||||
// Report credentials and alloc REST client.
|
||||
mxCredentials = credentials;
|
||||
_mxCredentials = credentials;
|
||||
[self prepareRESTClient];
|
||||
|
||||
userPresence = MXPresenceUnknown;
|
||||
@@ -171,65 +170,19 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)coder
|
||||
{
|
||||
self = [super init];
|
||||
self = [super initWithCoder:coder];
|
||||
|
||||
if (self)
|
||||
{
|
||||
notifyOpenSessionFailure = YES;
|
||||
|
||||
NSString *homeServerURL = [coder decodeObjectForKey:@"homeserverurl"];
|
||||
NSString *userId = [coder decodeObjectForKey:@"userid"];
|
||||
NSString *accessToken = [coder decodeObjectForKey:@"accesstoken"];
|
||||
_identityServerURL = [coder decodeObjectForKey:@"identityserverurl"];
|
||||
NSString *identityServerAccessToken = [coder decodeObjectForKey:@"identityserveraccesstoken"];
|
||||
|
||||
mxCredentials = [[MXCredentials alloc] initWithHomeServer:homeServerURL
|
||||
userId:userId
|
||||
accessToken:accessToken];
|
||||
|
||||
mxCredentials.identityServer = _identityServerURL;
|
||||
mxCredentials.identityServerAccessToken = identityServerAccessToken;
|
||||
mxCredentials.deviceId = [coder decodeObjectForKey:@"deviceId"];
|
||||
mxCredentials.allowedCertificate = [coder decodeObjectForKey:@"allowedCertificate"];
|
||||
|
||||
[self prepareRESTClient];
|
||||
|
||||
[self registerAccountDataDidChangeIdentityServerNotification];
|
||||
[self registerIdentityServiceDidChangeAccessTokenNotification];
|
||||
|
||||
if ([coder decodeObjectForKey:@"threePIDs"])
|
||||
{
|
||||
threePIDs = [coder decodeObjectForKey:@"threePIDs"];
|
||||
}
|
||||
|
||||
if ([coder decodeObjectForKey:@"device"])
|
||||
{
|
||||
_device = [coder decodeObjectForKey:@"device"];
|
||||
}
|
||||
|
||||
userPresence = MXPresenceUnknown;
|
||||
|
||||
if ([coder decodeObjectForKey:@"antivirusserverurl"])
|
||||
{
|
||||
_antivirusServerURL = [coder decodeObjectForKey:@"antivirusserverurl"];
|
||||
}
|
||||
|
||||
if ([coder decodeObjectForKey:@"pushgatewayurl"])
|
||||
{
|
||||
_pushGatewayURL = [coder decodeObjectForKey:@"pushgatewayurl"];
|
||||
}
|
||||
|
||||
_hasPusherForPushNotifications = [coder decodeBoolForKey:@"_enablePushNotifications"];
|
||||
_hasPusherForPushKitNotifications = [coder decodeBoolForKey:@"enablePushKitNotifications"];
|
||||
_enableInAppNotifications = [coder decodeBoolForKey:@"enableInAppNotifications"];
|
||||
|
||||
_disabled = [coder decodeBoolForKey:@"disabled"];
|
||||
_isSoftLogout = [coder decodeBoolForKey:@"isSoftLogout"];
|
||||
|
||||
_warnedAboutEncryption = [coder decodeBoolForKey:@"warnedAboutEncryption"];
|
||||
|
||||
_others = [coder decodeObjectForKey:@"others"];
|
||||
|
||||
// Refresh device information
|
||||
[self loadDeviceInformation:nil failure:nil];
|
||||
}
|
||||
@@ -237,60 +190,6 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)coder
|
||||
{
|
||||
[coder encodeObject:mxCredentials.homeServer forKey:@"homeserverurl"];
|
||||
[coder encodeObject:mxCredentials.userId forKey:@"userid"];
|
||||
[coder encodeObject:mxCredentials.accessToken forKey:@"accesstoken"];
|
||||
[coder encodeObject:mxCredentials.identityServerAccessToken forKey:@"identityserveraccesstoken"];
|
||||
|
||||
if (mxCredentials.deviceId)
|
||||
{
|
||||
[coder encodeObject:mxCredentials.deviceId forKey:@"deviceId"];
|
||||
}
|
||||
|
||||
if (mxCredentials.allowedCertificate)
|
||||
{
|
||||
[coder encodeObject:mxCredentials.allowedCertificate forKey:@"allowedCertificate"];
|
||||
}
|
||||
|
||||
if (self.threePIDs)
|
||||
{
|
||||
[coder encodeObject:threePIDs forKey:@"threePIDs"];
|
||||
}
|
||||
|
||||
if (self.device)
|
||||
{
|
||||
[coder encodeObject:_device forKey:@"device"];
|
||||
}
|
||||
|
||||
if (self.identityServerURL)
|
||||
{
|
||||
[coder encodeObject:_identityServerURL forKey:@"identityserverurl"];
|
||||
}
|
||||
|
||||
if (self.antivirusServerURL)
|
||||
{
|
||||
[coder encodeObject:_antivirusServerURL forKey:@"antivirusserverurl"];
|
||||
}
|
||||
|
||||
if (self.pushGatewayURL)
|
||||
{
|
||||
[coder encodeObject:_pushGatewayURL forKey:@"pushgatewayurl"];
|
||||
}
|
||||
|
||||
[coder encodeBool:_hasPusherForPushNotifications forKey:@"_enablePushNotifications"];
|
||||
[coder encodeBool:_hasPusherForPushKitNotifications forKey:@"enablePushKitNotifications"];
|
||||
[coder encodeBool:_enableInAppNotifications forKey:@"enableInAppNotifications"];
|
||||
|
||||
[coder encodeBool:_disabled forKey:@"disabled"];
|
||||
[coder encodeBool:_isSoftLogout forKey:@"isSoftLogout"];
|
||||
|
||||
[coder encodeBool:_warnedAboutEncryption forKey:@"warnedAboutEncryption"];
|
||||
|
||||
[coder encodeObject:_others forKey:@"others"];
|
||||
}
|
||||
|
||||
#pragma mark - Properties
|
||||
|
||||
- (void)setIdentityServerURL:(NSString *)identityServerURL
|
||||
@@ -298,10 +197,10 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
if (identityServerURL.length)
|
||||
{
|
||||
_identityServerURL = identityServerURL;
|
||||
mxCredentials.identityServer = identityServerURL;
|
||||
self.mxCredentials.identityServer = identityServerURL;
|
||||
|
||||
// Update services used in MXSession
|
||||
[mxSession setIdentityServer:mxCredentials.identityServer andAccessToken:mxCredentials.identityServerAccessToken];
|
||||
[mxSession setIdentityServer:self.mxCredentials.identityServer andAccessToken:self.mxCredentials.identityServerAccessToken];
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -355,24 +254,19 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
{
|
||||
if (self.userDisplayName.length)
|
||||
{
|
||||
return [NSString stringWithFormat:@"%@ (%@)", self.userDisplayName, mxCredentials.userId];
|
||||
return [NSString stringWithFormat:@"%@ (%@)", self.userDisplayName, self.mxCredentials.userId];
|
||||
}
|
||||
else
|
||||
{
|
||||
return mxCredentials.userId;
|
||||
return self.mxCredentials.userId;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSArray<MXThirdPartyIdentifier *> *)threePIDs
|
||||
{
|
||||
return threePIDs;
|
||||
}
|
||||
|
||||
- (NSArray<NSString *> *)linkedEmails
|
||||
{
|
||||
NSMutableArray<NSString *> *linkedEmails = [NSMutableArray array];
|
||||
|
||||
for (MXThirdPartyIdentifier *threePID in threePIDs)
|
||||
for (MXThirdPartyIdentifier *threePID in self.threePIDs)
|
||||
{
|
||||
if ([threePID.medium isEqualToString:kMX3PIDMediumEmail])
|
||||
{
|
||||
@@ -387,7 +281,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
{
|
||||
NSMutableArray<NSString *> *linkedPhoneNumbers = [NSMutableArray array];
|
||||
|
||||
for (MXThirdPartyIdentifier *threePID in threePIDs)
|
||||
for (MXThirdPartyIdentifier *threePID in self.threePIDs)
|
||||
{
|
||||
if ([threePID.medium isEqualToString:kMX3PIDMediumMSISDN])
|
||||
{
|
||||
@@ -402,7 +296,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
{
|
||||
if (!userTintColor)
|
||||
{
|
||||
userTintColor = [MXKTools colorWithRGBValue:[mxCredentials.userId hash]];
|
||||
userTintColor = [MXKTools colorWithRGBValue:[self.mxCredentials.userId hash]];
|
||||
}
|
||||
|
||||
return userTintColor;
|
||||
@@ -410,7 +304,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
|
||||
- (BOOL)pushNotificationServiceIsActive
|
||||
{
|
||||
BOOL pushNotificationServiceIsActive = ([[MXKAccountManager sharedManager] isAPNSAvailable] && _hasPusherForPushNotifications && mxSession);
|
||||
BOOL pushNotificationServiceIsActive = ([[MXKAccountManager sharedManager] isAPNSAvailable] && self.hasPusherForPushNotifications && mxSession);
|
||||
MXLogDebug(@"[MXKAccount][Push] pushNotificationServiceIsActive: %@", @(pushNotificationServiceIsActive));
|
||||
|
||||
return pushNotificationServiceIsActive;
|
||||
@@ -461,7 +355,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (_hasPusherForPushNotifications)
|
||||
else if (self.hasPusherForPushNotifications)
|
||||
{
|
||||
MXLogDebug(@"[MXKAccount][Push] enablePushNotifications: Disable APNS for %@ account", self.mxCredentials.userId);
|
||||
|
||||
@@ -487,7 +381,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
|
||||
- (BOOL)isPushKitNotificationActive
|
||||
{
|
||||
BOOL isPushKitNotificationActive = ([[MXKAccountManager sharedManager] isPushAvailable] && _hasPusherForPushKitNotifications && mxSession);
|
||||
BOOL isPushKitNotificationActive = ([[MXKAccountManager sharedManager] isPushAvailable] && self.hasPusherForPushKitNotifications && mxSession);
|
||||
MXLogDebug(@"[MXKAccount][Push] isPushKitNotificationActive: %@", @(isPushKitNotificationActive));
|
||||
|
||||
return isPushKitNotificationActive;
|
||||
@@ -535,7 +429,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
failure (error);
|
||||
}
|
||||
}
|
||||
else if (_hasPusherForPushKitNotifications)
|
||||
else if (self.hasPusherForPushKitNotifications)
|
||||
{
|
||||
MXLogDebug(@"[MXKAccount][Push] enablePushKitNotifications: Disable Push for %@ account", self.mxCredentials.userId);
|
||||
|
||||
@@ -633,7 +527,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
success();
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self->mxCredentials.userId];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self.mxCredentials.userId];
|
||||
}
|
||||
failure:failure];
|
||||
}
|
||||
@@ -653,7 +547,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
success();
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self->mxCredentials.userId];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self.mxCredentials.userId];
|
||||
}
|
||||
failure:failure];
|
||||
}
|
||||
@@ -686,9 +580,9 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
|
||||
- (void)load3PIDs:(void (^)(void))success failure:(void (^)(NSError *))failure
|
||||
{
|
||||
|
||||
[mxRestClient threePIDs:^(NSArray<MXThirdPartyIdentifier *> *threePIDs2) {
|
||||
|
||||
self->threePIDs = threePIDs2;
|
||||
self->_threePIDs = threePIDs2;
|
||||
|
||||
// Archive updated field
|
||||
[[MXKAccountManager sharedManager] saveAccounts];
|
||||
@@ -708,9 +602,9 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
|
||||
- (void)loadDeviceInformation:(void (^)(void))success failure:(void (^)(NSError *error))failure
|
||||
{
|
||||
if (mxCredentials.deviceId)
|
||||
if (self.mxCredentials.deviceId)
|
||||
{
|
||||
[mxRestClient deviceByDeviceId:mxCredentials.deviceId success:^(MXDevice *device) {
|
||||
[mxRestClient deviceByDeviceId:self.mxCredentials.deviceId success:^(MXDevice *device) {
|
||||
|
||||
self->_device = device;
|
||||
|
||||
@@ -751,21 +645,21 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
[mxSession.myUser setPresence:userPresence
|
||||
andStatusMessage:statusMessage
|
||||
success:^{
|
||||
MXLogDebug(@"[MXKAccount] %@: set user presence (%lu) succeeded", self->mxCredentials.userId, (unsigned long)self->userPresence);
|
||||
MXLogDebug(@"[MXKAccount] %@: set user presence (%lu) succeeded", self.mxCredentials.userId, (unsigned long)self->userPresence);
|
||||
if (completion)
|
||||
{
|
||||
completion();
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self->mxCredentials.userId];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self.mxCredentials.userId];
|
||||
}
|
||||
failure:^(NSError *error) {
|
||||
MXLogDebug(@"[MXKAccount] %@: set user presence (%lu) failed", self->mxCredentials.userId, (unsigned long)self->userPresence);
|
||||
MXLogDebug(@"[MXKAccount] %@: set user presence (%lu) failed", self.mxCredentials.userId, (unsigned long)self->userPresence);
|
||||
}];
|
||||
}
|
||||
else if (hideUserPresence)
|
||||
{
|
||||
MXLogDebug(@"[MXKAccount] %@: set user presence is disabled.", mxCredentials.userId);
|
||||
MXLogDebug(@"[MXKAccount] %@: set user presence is disabled.", self.mxCredentials.userId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -783,7 +677,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
-(void)openSessionWithStore:(id<MXStore>)store
|
||||
{
|
||||
// Sanity check
|
||||
if (!mxCredentials || !mxRestClient)
|
||||
if (!self.mxCredentials || !mxRestClient)
|
||||
{
|
||||
MXLogDebug(@"[MXKAccount] Matrix session cannot be created without credentials");
|
||||
return;
|
||||
@@ -1048,9 +942,9 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
- (void)hydrateWithCredentials:(MXCredentials*)credentials
|
||||
{
|
||||
// Sanity check
|
||||
if ([mxCredentials.userId isEqualToString:credentials.userId])
|
||||
if ([self.mxCredentials.userId isEqualToString:credentials.userId])
|
||||
{
|
||||
mxCredentials = credentials;
|
||||
_mxCredentials = credentials;
|
||||
_isSoftLogout = NO;
|
||||
[[MXKAccountManager sharedManager] saveAccounts];
|
||||
|
||||
@@ -1058,11 +952,10 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
}
|
||||
else
|
||||
{
|
||||
MXLogDebug(@"[MXKAccount] hydrateWithCredentials: Error: users ids mismatch: %@ vs %@", credentials.userId, mxCredentials.userId);
|
||||
MXLogDebug(@"[MXKAccount] hydrateWithCredentials: Error: users ids mismatch: %@ vs %@", credentials.userId, self.mxCredentials.userId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
- (void)deletePusher
|
||||
{
|
||||
if (self.pushNotificationServiceIsActive)
|
||||
@@ -1259,7 +1152,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
success();
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self->mxCredentials.userId];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
@@ -1278,7 +1171,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
success();
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self->mxCredentials.userId];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId];
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1295,7 +1188,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
failure(error);
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self->mxCredentials.userId];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountAPNSActivityDidChangeNotification object:self.mxCredentials.userId];
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -1322,7 +1215,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
MXLogDebug(@"[MXKAccount][Push] refreshPushKitPusher: Error: %@", error);
|
||||
}];
|
||||
}
|
||||
else if (_hasPusherForPushKitNotifications)
|
||||
else if (self.hasPusherForPushKitNotifications)
|
||||
{
|
||||
if ([MXKAccountManager sharedManager].pushDeviceToken)
|
||||
{
|
||||
@@ -1336,7 +1229,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
else
|
||||
{
|
||||
MXLogDebug(@"[MXKAccount][Push] refreshPushKitPusher: PushKit pusher for %@ account is already disabled. Reset _hasPusherForPushKitNotifications", self.mxCredentials.userId);
|
||||
_hasPusherForPushKitNotifications = NO;
|
||||
self->_hasPusherForPushKitNotifications = NO;
|
||||
[[MXKAccountManager sharedManager] saveAccounts];
|
||||
}
|
||||
}
|
||||
@@ -1398,7 +1291,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
success();
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountPushKitActivityDidChangeNotification object:self->mxCredentials.userId];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountPushKitActivityDidChangeNotification object:self.mxCredentials.userId];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
@@ -1417,7 +1310,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
success();
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountPushKitActivityDidChangeNotification object:self->mxCredentials.userId];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountPushKitActivityDidChangeNotification object:self.mxCredentials.userId];
|
||||
|
||||
return;
|
||||
}
|
||||
@@ -1434,7 +1327,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
failure(error);
|
||||
}
|
||||
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountPushKitActivityDidChangeNotification object:self->mxCredentials.userId];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountPushKitActivityDidChangeNotification object:self.mxCredentials.userId];
|
||||
}];
|
||||
}
|
||||
|
||||
@@ -1443,7 +1336,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
MXLogDebug(@"[MXKAccount][Push] enablePusher: %@", @(enabled));
|
||||
|
||||
// Refuse to try & turn push on if we're not logged in, it's nonsensical.
|
||||
if (!mxCredentials)
|
||||
if (!self.mxCredentials)
|
||||
{
|
||||
MXLogDebug(@"[MXKAccount][Push] enablePusher: Not setting push token because we're not logged in");
|
||||
return;
|
||||
@@ -1610,7 +1503,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
[self.mxSession startWithSyncFilter:syncFilter onServerSyncDone:^{
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
MXLogDebug(@"[MXKAccount] %@: The session is ready. Matrix SDK session has been started in %0.fms.", self->mxCredentials.userId, [[NSDate date] timeIntervalSinceDate:self->openSessionStartDate] * 1000);
|
||||
MXLogDebug(@"[MXKAccount] %@: The session is ready. Matrix SDK session has been started in %0.fms.", self.mxCredentials.userId, [[NSDate date] timeIntervalSinceDate:self->openSessionStartDate] * 1000);
|
||||
|
||||
[self setUserPresence:MXPresenceOnline andStatusMessage:nil completion:nil];
|
||||
|
||||
@@ -1745,11 +1638,11 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
}
|
||||
|
||||
// Here displayname or other information have been updated, post update notification.
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self->mxCredentials.userId];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self.mxCredentials.userId];
|
||||
}];
|
||||
|
||||
// User information are just up-to-date (`mxSession` is running), post update notification.
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:mxCredentials.userId];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self.mxCredentials.userId];
|
||||
}
|
||||
}
|
||||
else if (mxSession.state == MXSessionStateStoreDataReady || mxSession.state == MXSessionStateSyncInProgress)
|
||||
@@ -1764,40 +1657,30 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
{
|
||||
// Here the initial server sync is in progress. The session is not running yet, but some user's information are available (from local storage).
|
||||
// We post update notification to let observer take into account this user's information even if they may not be up-to-date.
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:mxCredentials.userId];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKAccountUserInfoDidChangeNotification object:self.mxCredentials.userId];
|
||||
}
|
||||
}
|
||||
else if (mxSession.state == MXSessionStatePaused)
|
||||
{
|
||||
isPauseRequested = NO;
|
||||
}
|
||||
else if (mxSession.state == MXSessionStateUnknownToken)
|
||||
{
|
||||
// Logout this account
|
||||
[[MXKAccountManager sharedManager] removeAccount:self completion:nil];
|
||||
}
|
||||
else if (mxSession.state == MXSessionStateSoftLogout)
|
||||
{
|
||||
// Soft logout this account
|
||||
[[MXKAccountManager sharedManager] softLogout:self];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)prepareRESTClient
|
||||
{
|
||||
if (!mxCredentials)
|
||||
if (!self.mxCredentials)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
mxRestClient = [[MXRestClient alloc] initWithCredentials:mxCredentials andOnUnrecognizedCertificateBlock:^BOOL(NSData *certificate) {
|
||||
|
||||
MXWeakify(self);
|
||||
mxRestClient = [[MXRestClient alloc] initWithCredentials:self.mxCredentials andOnUnrecognizedCertificateBlock:^BOOL(NSData *certificate) {
|
||||
MXStrongifyAndReturnValueIfNil(self, NO);
|
||||
if (_onCertificateChangeBlock)
|
||||
{
|
||||
if (_onCertificateChangeBlock (self, certificate))
|
||||
{
|
||||
// Update the certificate in credentials
|
||||
self->mxCredentials.allowedCertificate = certificate;
|
||||
self.mxCredentials.allowedCertificate = certificate;
|
||||
|
||||
// Archive updated field
|
||||
[[MXKAccountManager sharedManager] saveAccounts];
|
||||
@@ -1805,16 +1688,39 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
return YES;
|
||||
}
|
||||
|
||||
self->mxCredentials.ignoredCertificate = certificate;
|
||||
self.mxCredentials.ignoredCertificate = certificate;
|
||||
|
||||
// Archive updated field
|
||||
[[MXKAccountManager sharedManager] saveAccounts];
|
||||
}
|
||||
return NO;
|
||||
|
||||
} andPersistentTokenDataHandler:^(void (^handler)(NSArray<MXCredentials *> *credentials, void (^completion)(BOOL didUpdateCredentials))) {
|
||||
[MXKAccountManager.sharedManager readAndWriteCredentials:handler];
|
||||
} andUnauthenticatedHandler:^(MXError *error, BOOL isSoftLogout, BOOL isRefreshTokenAuth, void (^completion)(void)) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
[self handleUnauthenticatedWithError:error isSoftLogout:isSoftLogout isRefreshTokenAuth:isRefreshTokenAuth andCompletion:completion];
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)handleUnauthenticatedWithError:(MXError *)error isSoftLogout:(BOOL)isSoftLogout isRefreshTokenAuth:(BOOL)isRefreshTokenAuth andCompletion:(void (^)(void))completion
|
||||
{
|
||||
|
||||
[Analytics.shared trackAuthUnauthenticatedErrorWithSoftLogout:isSoftLogout refreshTokenAuth:isRefreshTokenAuth errorCode:error.errcode errorReason:error.error];
|
||||
MXLogDebug(@"[MXKAccountManager] handleUnauthenticated: trackAuthUnauthenticatedErrorWithSoftLogout sent");
|
||||
if (isSoftLogout)
|
||||
{
|
||||
MXLogDebug(@"[MXKAccountManager] handleUnauthenticated: soft logout.");
|
||||
[[MXKAccountManager sharedManager] softLogout:self];
|
||||
completion();
|
||||
}
|
||||
else
|
||||
{
|
||||
MXLogDebug(@"[MXKAccountManager] handleUnauthenticated: hard logout.");
|
||||
[[MXKAccountManager sharedManager] removeAccount:self sendLogoutRequest:NO completion:completion];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onDateTimeFormatUpdate
|
||||
{
|
||||
if ([mxSession.roomSummaryUpdateDelegate isKindOfClass:MXKEventFormatter.class])
|
||||
@@ -1871,7 +1777,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
#pragma mark - Crypto
|
||||
- (void)resetDeviceId
|
||||
{
|
||||
mxCredentials.deviceId = nil;
|
||||
self.mxCredentials.deviceId = nil;
|
||||
|
||||
// Archive updated field
|
||||
[[MXKAccountManager sharedManager] saveAccounts];
|
||||
@@ -2187,11 +2093,11 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
MXSession *mxSession = notification.object;
|
||||
if (mxSession == self.mxSession)
|
||||
{
|
||||
if (![mxCredentials.identityServer isEqualToString:self.mxSession.accountDataIdentityServer])
|
||||
if (![self.mxCredentials.identityServer isEqualToString:self.mxSession.accountDataIdentityServer])
|
||||
{
|
||||
_identityServerURL = self.mxSession.accountDataIdentityServer;
|
||||
mxCredentials.identityServer = _identityServerURL;
|
||||
mxCredentials.identityServerAccessToken = nil;
|
||||
self.mxCredentials.identityServer = _identityServerURL;
|
||||
self.mxCredentials.identityServerAccessToken = nil;
|
||||
|
||||
// Archive updated field
|
||||
[[MXKAccountManager sharedManager] saveAccounts];
|
||||
@@ -2204,7 +2110,7 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
|
||||
- (void)identityService:(MXIdentityService *)identityService didUpdateAccessToken:(NSString *)accessToken
|
||||
{
|
||||
mxCredentials.identityServerAccessToken = accessToken;
|
||||
self.mxCredentials.identityServerAccessToken = accessToken;
|
||||
}
|
||||
|
||||
- (void)registerIdentityServiceDidChangeAccessTokenNotification
|
||||
@@ -2220,9 +2126,9 @@ static NSArray<NSNumber*> *initialSyncSilentErrorsHTTPStatusCodes;
|
||||
NSString *identityServer = userInfo[MXIdentityServiceNotificationIdentityServerKey];
|
||||
NSString *accessToken = userInfo[MXIdentityServiceNotificationAccessTokenKey];
|
||||
|
||||
if (userId && identityServer && accessToken && [mxCredentials.identityServer isEqualToString:identityServer])
|
||||
if (userId && identityServer && accessToken && [self.mxCredentials.identityServer isEqualToString:identityServer])
|
||||
{
|
||||
mxCredentials.identityServerAccessToken = accessToken;
|
||||
self.mxCredentials.identityServerAccessToken = accessToken;
|
||||
|
||||
// Archive updated field
|
||||
[[MXKAccountManager sharedManager] saveAccounts];
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
//
|
||||
// Copyright 2021 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#import <MatrixSDK/MatrixSDK.h>
|
||||
|
||||
@class MXKAccountData;
|
||||
|
||||
@interface MXKAccountData : NSObject <NSCoding> {
|
||||
|
||||
@protected MXCredentials *_mxCredentials;
|
||||
@protected NSString *_identityServerURL;
|
||||
@protected NSString *_antivirusServerURL;
|
||||
@protected NSString *_pushGatewayURL;
|
||||
@protected MXDevice *_device;
|
||||
@protected BOOL _disabled;
|
||||
@protected BOOL _enableInAppNotifications;
|
||||
@protected BOOL _warnedAboutEncryption;
|
||||
@protected NSMutableDictionary<NSString *, id<NSCoding>> *_others;
|
||||
@protected NSArray<MXThirdPartyIdentifier *> *_threePIDs;
|
||||
@protected BOOL _isSoftLogout;
|
||||
@protected BOOL _hasPusherForPushNotifications;
|
||||
@protected BOOL _hasPusherForPushKitNotifications;
|
||||
}
|
||||
|
||||
/**
|
||||
The account's credentials: homeserver, access token, user id.
|
||||
*/
|
||||
@property (nonatomic, readonly, nonnull) MXCredentials *mxCredentials;
|
||||
|
||||
/**
|
||||
The identity server URL.
|
||||
*/
|
||||
@property (nonatomic, nonnull) NSString *identityServerURL;
|
||||
|
||||
/**
|
||||
The antivirus server URL, if any (nil by default).
|
||||
Set a non-null url to configure the antivirus scanner use.
|
||||
*/
|
||||
@property (nonatomic, nullable) NSString *antivirusServerURL;
|
||||
|
||||
/**
|
||||
The Push Gateway URL used to send event notifications to (nil by default).
|
||||
This URL should be over HTTPS and never over HTTP.
|
||||
*/
|
||||
@property (nonatomic, nullable) NSString *pushGatewayURL;
|
||||
|
||||
/**
|
||||
The 3PIDs linked to this account.
|
||||
[self load3PIDs] must be called to update the property.
|
||||
*/
|
||||
@property (nonatomic, readonly, nullable) NSArray<MXThirdPartyIdentifier *> *threePIDs;
|
||||
|
||||
/**
|
||||
The account user's device.
|
||||
[self loadDeviceInformation] must be called to update the property.
|
||||
*/
|
||||
@property (nonatomic, readonly, nullable) MXDevice *device;
|
||||
|
||||
/**
|
||||
Transient information storage.
|
||||
*/
|
||||
@property (nonatomic, strong, readonly, nonnull) NSMutableDictionary<NSString *, id<NSCoding>> *others;
|
||||
|
||||
/**
|
||||
Flag to indicate that an APNS pusher has been set on the homeserver for this device.
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL hasPusherForPushNotifications;
|
||||
|
||||
/**
|
||||
The Push notification activity (based on PushKit) for this account.
|
||||
YES when Push is turned on (locally available and enabled homeserver side).
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL isPushKitNotificationActive;
|
||||
|
||||
/**
|
||||
Flag to indicate that a PushKit pusher has been set on the homeserver for this device.
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL hasPusherForPushKitNotifications;
|
||||
|
||||
|
||||
/**
|
||||
Enable In-App notifications based on Remote notifications rules.
|
||||
NO by default.
|
||||
*/
|
||||
@property (nonatomic) BOOL enableInAppNotifications;
|
||||
|
||||
/**
|
||||
Disable the account without logging out (NO by default).
|
||||
|
||||
A matrix session is automatically opened for the account when this property is toggled from YES to NO.
|
||||
The session is closed when this property is set to YES.
|
||||
*/
|
||||
@property (nonatomic,getter=isDisabled) BOOL disabled;
|
||||
|
||||
/**
|
||||
Flag indicating if the end user has been warned about encryption and its limitations.
|
||||
*/
|
||||
@property (nonatomic,getter=isWarnedAboutEncryption) BOOL warnedAboutEncryption;
|
||||
|
||||
#pragma mark - Soft logout
|
||||
|
||||
/**
|
||||
Flag to indicate if the account has been logged out by the homeserver admin.
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL isSoftLogout;
|
||||
@end
|
||||
@@ -0,0 +1,150 @@
|
||||
//
|
||||
// Copyright 2021 New Vector Ltd
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "MXKAccountData.h"
|
||||
|
||||
@interface MXKAccountData ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation MXKAccountData
|
||||
|
||||
@synthesize mxCredentials = _mxCredentials;
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
- (id)initWithCoder:(NSCoder *)coder
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self)
|
||||
{
|
||||
|
||||
NSString *homeServerURL = [coder decodeObjectForKey:@"homeserverurl"];
|
||||
NSString *userId = [coder decodeObjectForKey:@"userid"];
|
||||
NSString *accessToken = [coder decodeObjectForKey:@"accesstoken"];
|
||||
_identityServerURL = [coder decodeObjectForKey:@"identityserverurl"];
|
||||
NSString *identityServerAccessToken = [coder decodeObjectForKey:@"identityserveraccesstoken"];
|
||||
|
||||
_mxCredentials = [[MXCredentials alloc] initWithHomeServer:homeServerURL
|
||||
userId:userId
|
||||
accessToken:accessToken];
|
||||
|
||||
_mxCredentials.accessTokenExpiresAt = [coder decodeInt64ForKey:@"accessTokenExpiresAt"];
|
||||
_mxCredentials.refreshToken = [coder decodeObjectForKey:@"refreshToken"];
|
||||
_mxCredentials.identityServer = _identityServerURL;
|
||||
_mxCredentials.identityServerAccessToken = identityServerAccessToken;
|
||||
_mxCredentials.deviceId = [coder decodeObjectForKey:@"deviceId"];
|
||||
_mxCredentials.allowedCertificate = [coder decodeObjectForKey:@"allowedCertificate"];
|
||||
|
||||
if ([coder decodeObjectForKey:@"threePIDs"])
|
||||
{
|
||||
_threePIDs = [coder decodeObjectForKey:@"threePIDs"];
|
||||
}
|
||||
|
||||
if ([coder decodeObjectForKey:@"device"])
|
||||
{
|
||||
_device = [coder decodeObjectForKey:@"device"];
|
||||
}
|
||||
|
||||
if ([coder decodeObjectForKey:@"antivirusserverurl"])
|
||||
{
|
||||
_antivirusServerURL = [coder decodeObjectForKey:@"antivirusserverurl"];
|
||||
}
|
||||
|
||||
if ([coder decodeObjectForKey:@"pushgatewayurl"])
|
||||
{
|
||||
_pushGatewayURL = [coder decodeObjectForKey:@"pushgatewayurl"];
|
||||
}
|
||||
|
||||
_hasPusherForPushNotifications = [coder decodeBoolForKey:@"_enablePushNotifications"];
|
||||
_hasPusherForPushKitNotifications = [coder decodeBoolForKey:@"enablePushKitNotifications"];
|
||||
_enableInAppNotifications = [coder decodeBoolForKey:@"enableInAppNotifications"];
|
||||
|
||||
_disabled = [coder decodeBoolForKey:@"disabled"];
|
||||
_isSoftLogout = [coder decodeBoolForKey:@"isSoftLogout"];
|
||||
|
||||
_warnedAboutEncryption = [coder decodeBoolForKey:@"warnedAboutEncryption"];
|
||||
|
||||
_others = [coder decodeObjectForKey:@"others"];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)coder
|
||||
{
|
||||
[coder encodeObject:_mxCredentials.homeServer forKey:@"homeserverurl"];
|
||||
[coder encodeObject:_mxCredentials.userId forKey:@"userid"];
|
||||
[coder encodeObject:_mxCredentials.accessToken forKey:@"accesstoken"];
|
||||
if (self.mxCredentials.accessTokenExpiresAt) {
|
||||
[coder encodeInt64:_mxCredentials.accessTokenExpiresAt forKey:@"accessTokenExpiresAt"];
|
||||
}
|
||||
if (self.mxCredentials.refreshToken) {
|
||||
[coder encodeObject:_mxCredentials.refreshToken forKey:@"refreshToken"];
|
||||
}
|
||||
[coder encodeObject:_mxCredentials.identityServerAccessToken forKey:@"identityserveraccesstoken"];
|
||||
|
||||
if (self.mxCredentials.deviceId)
|
||||
{
|
||||
[coder encodeObject:_mxCredentials.deviceId forKey:@"deviceId"];
|
||||
}
|
||||
|
||||
if (self.mxCredentials.allowedCertificate)
|
||||
{
|
||||
[coder encodeObject:_mxCredentials.allowedCertificate forKey:@"allowedCertificate"];
|
||||
}
|
||||
|
||||
if (self.threePIDs)
|
||||
{
|
||||
[coder encodeObject:_threePIDs forKey:@"threePIDs"];
|
||||
}
|
||||
|
||||
if (self.device)
|
||||
{
|
||||
[coder encodeObject:_device forKey:@"device"];
|
||||
}
|
||||
|
||||
if (self.identityServerURL)
|
||||
{
|
||||
[coder encodeObject:_identityServerURL forKey:@"identityserverurl"];
|
||||
}
|
||||
|
||||
if (self.antivirusServerURL)
|
||||
{
|
||||
[coder encodeObject:_antivirusServerURL forKey:@"antivirusserverurl"];
|
||||
}
|
||||
|
||||
if (self.pushGatewayURL)
|
||||
{
|
||||
[coder encodeObject:_pushGatewayURL forKey:@"pushgatewayurl"];
|
||||
}
|
||||
|
||||
[coder encodeBool:_hasPusherForPushNotifications forKey:@"_enablePushNotifications"];
|
||||
[coder encodeBool:_hasPusherForPushKitNotifications forKey:@"enablePushKitNotifications"];
|
||||
[coder encodeBool:_enableInAppNotifications forKey:@"enableInAppNotifications"];
|
||||
|
||||
[coder encodeBool:_disabled forKey:@"disabled"];
|
||||
[coder encodeBool:_isSoftLogout forKey:@"isSoftLogout"];
|
||||
|
||||
[coder encodeBool:_warnedAboutEncryption forKey:@"warnedAboutEncryption"];
|
||||
|
||||
[coder encodeObject:_others forKey:@"others"];
|
||||
}
|
||||
|
||||
|
||||
@end
|
||||
@@ -110,6 +110,8 @@ extern NSString *const MXKAccountManagerDataType;
|
||||
*/
|
||||
+ (MXKAccountManager *)sharedManager;
|
||||
|
||||
+ (MXKAccountManager *)sharedManagerWithReload:(BOOL)reload;
|
||||
|
||||
/**
|
||||
Check for each enabled account if a matrix session is already opened.
|
||||
Open a matrix session for each enabled account which doesn't have a session.
|
||||
@@ -208,11 +210,6 @@ extern NSString *const MXKAccountManagerDataType;
|
||||
*/
|
||||
- (MXKAccount *)accountKnowingUserWithUserId:(NSString *)userId;
|
||||
|
||||
/**
|
||||
Force the account manager to reload existing accounts from the local storage.
|
||||
The account manager is supposed to handle itself the list of the accounts.
|
||||
Call this method only when an account has been changed from an other application from the same group.
|
||||
*/
|
||||
- (void)forceReloadAccounts;
|
||||
- (void)readAndWriteCredentials:(void (^)(NSArray<MXCredentials*> * _Nullable readData, void (^completion)(BOOL didUpdateCredentials)))readAnWriteHandler;
|
||||
|
||||
@end
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
#import "MXKAppSettings.h"
|
||||
|
||||
#import "MXKTools.h"
|
||||
#import "MXKAccountData.h"
|
||||
#import "MXRefreshTokenData.h"
|
||||
|
||||
static NSString *const kMXKAccountsKeyOld = @"accounts";
|
||||
static NSString *const kMXKAccountsKey = @"accountsV2";
|
||||
@@ -43,13 +45,23 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
|
||||
@implementation MXKAccountManager
|
||||
|
||||
+ (MXKAccountManager *)sharedManager
|
||||
{
|
||||
return [MXKAccountManager sharedManagerWithReload:NO];
|
||||
}
|
||||
|
||||
+ (MXKAccountManager *)sharedManagerWithReload:(BOOL)reload
|
||||
{
|
||||
static MXKAccountManager *sharedAccountManager = nil;
|
||||
static dispatch_once_t onceToken;
|
||||
__block BOOL didLoad = false;
|
||||
dispatch_once(&onceToken, ^{
|
||||
didLoad = true;
|
||||
sharedAccountManager = [[super allocWithZone:NULL] init];
|
||||
});
|
||||
|
||||
if (reload && !didLoad) {
|
||||
[sharedAccountManager loadAccounts];
|
||||
}
|
||||
return sharedAccountManager;
|
||||
}
|
||||
|
||||
@@ -599,7 +611,6 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
|
||||
- (void)loadAccounts
|
||||
{
|
||||
MXLogDebug(@"[MXKAccountManager] loadAccounts");
|
||||
|
||||
NSString *accountFile = [self accountFile];
|
||||
if ([[NSFileManager defaultManager] fileExistsAtPath:accountFile])
|
||||
{
|
||||
@@ -665,12 +676,6 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
|
||||
}
|
||||
}
|
||||
|
||||
- (void)forceReloadAccounts
|
||||
{
|
||||
MXLogDebug(@"[MXKAccountManager] Force reload existing accounts from local storage");
|
||||
[self loadAccounts];
|
||||
}
|
||||
|
||||
- (NSData*)encryptData:(NSData*)data
|
||||
{
|
||||
// Exceptions are not caught as the key is always needed if the KeyProviderDelegate
|
||||
@@ -723,4 +728,69 @@ NSString *const MXKAccountManagerDataType = @"org.matrix.kit.MXKAccountManagerDa
|
||||
}
|
||||
}
|
||||
|
||||
- (void)readAndWriteCredentials:(void (^)(NSArray<MXCredentials*> * _Nullable readData, void (^completion)(BOOL didUpdateCredentials)))readAnWriteHandler
|
||||
{
|
||||
NSError *error;
|
||||
NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init];
|
||||
__block BOOL coordinatorSuccess = NO;
|
||||
MXLogDebug(@"[MXKAccountManager] readAndWriteCredentials: purposeIdentifier = %@", fileCoordinator.purposeIdentifier);
|
||||
NSDate *coordinateStartTime = [NSDate date];
|
||||
[fileCoordinator coordinateReadingItemAtURL:[self accountFileUrl]
|
||||
options:0
|
||||
writingItemAtURL:[self accountFileUrl]
|
||||
options:NSFileCoordinatorWritingForMerging
|
||||
error:&error
|
||||
byAccessor:^(NSURL * _Nonnull newReadingURL, NSURL * _Nonnull newWritingURL) {
|
||||
|
||||
NSDate *accessorStartTime = [NSDate date];
|
||||
NSTimeInterval acquireInterval = [accessorStartTime timeIntervalSinceDate:coordinateStartTime];
|
||||
MXLogDebug(@"[MXKAccountManager] readAndWriteCredentials: acquireInterval = %f", acquireInterval);
|
||||
NSError *error = nil;
|
||||
NSData* data = [NSData dataWithContentsOfURL:newReadingURL options:(NSDataReadingMappedAlways | NSDataReadingUncached) error:&error];
|
||||
|
||||
// Decrypt data if encryption method is provided
|
||||
NSData *unciphered = [self decryptData:data];
|
||||
NSKeyedUnarchiver *decoder = [[NSKeyedUnarchiver alloc] initForReadingFromData:unciphered error:&error];
|
||||
decoder.requiresSecureCoding = false;
|
||||
[decoder setClass:[MXKAccountData class] forClassName:@"MXKAccount"];
|
||||
NSMutableArray<MXKAccountData*>* mxAccountsData = [decoder decodeObjectForKey:@"mxAccounts"];
|
||||
NSMutableArray<MXCredentials*>* mxAccountCredentials = [NSMutableArray arrayWithCapacity:mxAccounts.count];
|
||||
for(MXKAccountData *account in mxAccountsData){
|
||||
[mxAccountCredentials addObject:account.mxCredentials];
|
||||
}
|
||||
|
||||
dispatch_group_t dispatchGroup = dispatch_group_create();
|
||||
dispatch_group_enter(dispatchGroup);
|
||||
|
||||
__block BOOL didUpdate = NO;
|
||||
readAnWriteHandler(mxAccountCredentials, ^(BOOL didUpdateCredentials) {
|
||||
didUpdate = didUpdateCredentials;
|
||||
dispatch_group_leave(dispatchGroup);
|
||||
});
|
||||
|
||||
dispatch_group_wait(dispatchGroup, DISPATCH_TIME_FOREVER);
|
||||
|
||||
if (didUpdate) {
|
||||
MXLogDebug(@"[MXKAccountManager] readAndWriteCredentials: did update saving credential data");
|
||||
NSKeyedArchiver *encoder = [[NSKeyedArchiver alloc] initRequiringSecureCoding: NO];
|
||||
[encoder setClassName:@"MXKAccount" forClass:[MXKAccountData class]];
|
||||
[encoder encodeObject:mxAccountsData forKey:@"mxAccounts"];
|
||||
NSData *writeData = [self encryptData:[encoder encodedData]];
|
||||
coordinatorSuccess = [writeData writeToURL:newWritingURL atomically:YES];
|
||||
} else {
|
||||
MXLogDebug(@"[MXKAccountManager] readAndWriteCredentials: did not update not saving credential data");
|
||||
coordinatorSuccess = YES;
|
||||
}
|
||||
NSDate *accessorEndTime = [NSDate date];
|
||||
NSTimeInterval lockedTime = [accessorEndTime timeIntervalSinceDate:accessorStartTime];
|
||||
MXLogDebug(@"[MXKAccountManager] readAndWriteCredentials: lockedTime = %f", lockedTime);
|
||||
}];
|
||||
MXLogDebug(@"[MXKAccountManager] readAndWriteCredentials:exit %d", coordinatorSuccess);
|
||||
}
|
||||
|
||||
- (NSURL *)accountFileUrl
|
||||
{
|
||||
return [NSURL fileURLWithPath: [self accountFile]];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -27,7 +27,7 @@ extern NSString * const kMXKAttachmentErrorDomain;
|
||||
/**
|
||||
List attachment types
|
||||
*/
|
||||
typedef enum : NSUInteger {
|
||||
typedef NS_ENUM(NSUInteger, MXKAttachmentType) {
|
||||
MXKAttachmentTypeUndefined,
|
||||
MXKAttachmentTypeImage,
|
||||
MXKAttachmentTypeAudio,
|
||||
@@ -35,8 +35,7 @@ typedef enum : NSUInteger {
|
||||
MXKAttachmentTypeVideo,
|
||||
MXKAttachmentTypeFile,
|
||||
MXKAttachmentTypeSticker
|
||||
|
||||
} MXKAttachmentType;
|
||||
};
|
||||
|
||||
/**
|
||||
`MXKAttachment` represents a room attachment.
|
||||
|
||||
@@ -50,7 +50,8 @@
|
||||
The optional text pattern to be highlighted in the body of the message.
|
||||
*/
|
||||
NSString *highlightedPattern;
|
||||
UIColor *highlightedPatternColor;
|
||||
UIColor *highlightedPatternForegroundColor;
|
||||
UIColor *highlightedPatternBackgroundColor;
|
||||
UIFont *highlightedPatternFont;
|
||||
}
|
||||
|
||||
@@ -80,6 +81,11 @@
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL hasLink;
|
||||
|
||||
/**
|
||||
Whether the data has a thread root in its components.
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL hasThreadRoot;
|
||||
|
||||
/**
|
||||
Event formatter
|
||||
*/
|
||||
@@ -163,4 +169,11 @@
|
||||
*/
|
||||
- (MXKRoomBubbleComponent*)getFirstBubbleComponentWithDisplay;
|
||||
|
||||
/**
|
||||
Get the last visible component.
|
||||
|
||||
@return Last visible component or nil.
|
||||
*/
|
||||
- (MXKRoomBubbleComponent*)getLastBubbleComponentWithDisplay;
|
||||
|
||||
@end
|
||||
|
||||
@@ -306,16 +306,15 @@
|
||||
return first;
|
||||
}
|
||||
|
||||
- (MXKRoomBubbleComponent*) getFirstBubbleComponentWithDisplay
|
||||
- (MXKRoomBubbleComponent*)getFirstBubbleComponentWithDisplay
|
||||
{
|
||||
// Look for the first component which is actually displayed (some event are ignored in room history display).
|
||||
MXKRoomBubbleComponent* first = nil;
|
||||
|
||||
@synchronized(bubbleComponents)
|
||||
{
|
||||
for (NSInteger index = 0; index < bubbleComponents.count; index++)
|
||||
for (MXKRoomBubbleComponent *component in bubbleComponents)
|
||||
{
|
||||
MXKRoomBubbleComponent *component = bubbleComponents[index];
|
||||
if (component.attributedTextMessage)
|
||||
{
|
||||
first = component;
|
||||
@@ -327,6 +326,26 @@
|
||||
return first;
|
||||
}
|
||||
|
||||
- (MXKRoomBubbleComponent*)getLastBubbleComponentWithDisplay
|
||||
{
|
||||
// Look for the first component which is actually displayed (some event are ignored in room history display).
|
||||
MXKRoomBubbleComponent* lastVisibleComponent = nil;
|
||||
|
||||
@synchronized(bubbleComponents)
|
||||
{
|
||||
for (MXKRoomBubbleComponent *component in bubbleComponents.reverseObjectEnumerator)
|
||||
{
|
||||
if (component.attributedTextMessage)
|
||||
{
|
||||
lastVisibleComponent = component;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return lastVisibleComponent;
|
||||
}
|
||||
|
||||
- (NSAttributedString*)attributedTextMessageWithHighlightedEvent:(NSString*)eventId tintColor:(UIColor*)tintColor
|
||||
{
|
||||
NSAttributedString *customAttributedTextMsg;
|
||||
@@ -351,10 +370,14 @@
|
||||
return customAttributedTextMsg;
|
||||
}
|
||||
|
||||
- (void)highlightPatternInTextMessage:(NSString*)pattern withForegroundColor:(UIColor*)patternColor andFont:(UIFont*)patternFont
|
||||
- (void)highlightPatternInTextMessage:(NSString*)pattern
|
||||
withBackgroundColor:(UIColor *)backgroundColor
|
||||
foregroundColor:(UIColor*)foregroundColor
|
||||
andFont:(UIFont*)patternFont
|
||||
{
|
||||
highlightedPattern = pattern;
|
||||
highlightedPatternColor = patternColor;
|
||||
highlightedPatternBackgroundColor = backgroundColor;
|
||||
highlightedPatternForegroundColor = foregroundColor;
|
||||
highlightedPatternFont = patternFont;
|
||||
|
||||
// Indicate that the text message layout should be recomputed.
|
||||
@@ -607,6 +630,22 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)hasThreadRoot
|
||||
{
|
||||
@synchronized (bubbleComponents)
|
||||
{
|
||||
for (MXKRoomBubbleComponent *component in bubbleComponents)
|
||||
{
|
||||
if (component.thread)
|
||||
{
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (MXKRoomBubbleComponentDisplayFix)displayFix
|
||||
{
|
||||
MXKRoomBubbleComponentDisplayFix displayFix = MXKRoomBubbleComponentDisplayFixNone;
|
||||
@@ -705,6 +744,27 @@
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isAttachment
|
||||
{
|
||||
if (!self.attachment)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
if (!attachment.contentURL || !attachment.contentInfo) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
switch (self.attachment.type) {
|
||||
case MXKAttachmentTypeFile:
|
||||
case MXKAttachmentTypeAudio:
|
||||
case MXKAttachmentTypeVoiceMessage:
|
||||
return YES;
|
||||
default:
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setMaxTextViewWidth:(CGFloat)inMaxTextViewWidth
|
||||
{
|
||||
// Check change
|
||||
@@ -873,10 +933,16 @@
|
||||
|
||||
while (range.location != NSNotFound)
|
||||
{
|
||||
if (highlightedPatternColor)
|
||||
if (highlightedPatternBackgroundColor)
|
||||
{
|
||||
// Update background color
|
||||
[customAttributedTextMsg addAttribute:NSBackgroundColorAttributeName value:highlightedPatternBackgroundColor range:range];
|
||||
}
|
||||
|
||||
if (highlightedPatternForegroundColor)
|
||||
{
|
||||
// Update text color
|
||||
[customAttributedTextMsg addAttribute:NSForegroundColorAttributeName value:highlightedPatternColor range:range];
|
||||
[customAttributedTextMsg addAttribute:NSForegroundColorAttributeName value:highlightedPatternForegroundColor range:range];
|
||||
}
|
||||
|
||||
if (highlightedPatternFont)
|
||||
|
||||
@@ -147,6 +147,11 @@
|
||||
*/
|
||||
@property (nonatomic) BOOL isAttachmentWithIcon;
|
||||
|
||||
/**
|
||||
YES when the bubble correspond to an attachment (audio, file...).
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL isAttachment;
|
||||
|
||||
/**
|
||||
Flag that indicates that self.attributedTextMessage will be not nil.
|
||||
This avoids the computation of self.attributedTextMessage that can take time.
|
||||
@@ -269,10 +274,14 @@ Update the event because its sent state changed or it is has been redacted.
|
||||
Highlight all the occurrences of a pattern in the resulting message body 'attributedTextMessage'.
|
||||
|
||||
@param pattern the text pattern to highlight.
|
||||
@param patternColor optional text color (the pattern text color is unchanged if nil).
|
||||
@param backgroundColor optional text background color (the patterns background color is unchanged if nil)
|
||||
@param foregroundColor optional text color (the pattern text color is unchanged if nil).
|
||||
@param patternFont optional text font (the pattern font is unchanged if nil).
|
||||
*/
|
||||
- (void)highlightPatternInTextMessage:(NSString*)pattern withForegroundColor:(UIColor*)patternColor andFont:(UIFont*)patternFont;
|
||||
- (void)highlightPatternInTextMessage:(NSString*)pattern
|
||||
withBackgroundColor:(UIColor *)backgroundColor
|
||||
foregroundColor:(UIColor*)foregroundColor
|
||||
andFont:(UIFont*)patternFont;
|
||||
|
||||
/**
|
||||
Refresh the sender flair information
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
#import "MXKEventFormatter.h"
|
||||
#import "MXKURLPreviewDataProtocol.h"
|
||||
|
||||
@class MXThread;
|
||||
|
||||
/**
|
||||
Flags to indicate if a fix is required at the display time.
|
||||
*/
|
||||
@@ -103,6 +105,11 @@ typedef enum : NSUInteger {
|
||||
*/
|
||||
@property (nonatomic, readonly) BOOL showEncryptionBadge;
|
||||
|
||||
/**
|
||||
Thread for the bubble component. Should only exist for thread root events.
|
||||
*/
|
||||
@property (nonatomic, readonly) MXThread *thread;
|
||||
|
||||
/**
|
||||
Create a new `MXKRoomBubbleComponent` object based on a `MXEvent` instance.
|
||||
|
||||
|
||||
@@ -18,6 +18,13 @@
|
||||
|
||||
#import "MXEvent+MatrixKit.h"
|
||||
#import "MXKSwiftHeader.h"
|
||||
#import <MatrixSDK/MatrixSDK.h>
|
||||
|
||||
@interface MXKRoomBubbleComponent ()
|
||||
|
||||
@property (nonatomic, readwrite) MXThread *thread;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MXKRoomBubbleComponent
|
||||
|
||||
@@ -62,6 +69,8 @@
|
||||
_showEncryptionBadge = [self shouldShowWarningBadgeForEvent:event roomState:(MXRoomState*)roomState session:session];
|
||||
|
||||
[self updateLinkWithRoomState:roomState];
|
||||
|
||||
self.thread = [session.threadingService threadWithId:event.eventId];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ extern NSString *const kMXKRoomDataSourceTimelineErrorErrorKey;
|
||||
The timeline being managed. It can be the live timeline of the room
|
||||
or a timeline from a past event, initialEventId.
|
||||
*/
|
||||
@property (nonatomic, readonly) MXEventTimeline *timeline;
|
||||
@property (nonatomic, readonly) id<MXEventTimeline> timeline;
|
||||
|
||||
/**
|
||||
Flag indicating if the data source manages, or will manage, a live timeline.
|
||||
@@ -169,6 +169,11 @@ extern NSString *const kMXKRoomDataSourceTimelineErrorErrorKey;
|
||||
*/
|
||||
@property (nonatomic) NSString *partialTextMessage;
|
||||
|
||||
/**
|
||||
The current thread id for the data source. If provided, data source displays the specified thread, otherwise the whole room messages.
|
||||
*/
|
||||
@property (nonatomic, readonly) NSString *threadId;
|
||||
|
||||
#pragma mark - Configuration
|
||||
/**
|
||||
The text formatter applied on the events.
|
||||
@@ -269,10 +274,15 @@ extern NSString *const kMXKRoomDataSourceTimelineErrorErrorKey;
|
||||
|
||||
@param roomId the id of the room to get data from.
|
||||
@param initialEventId the id of the event where to start the timeline.
|
||||
@param threadId the id of the thread to load. If provided, thread data source will be loaded from the room specified with `roomId`.
|
||||
@param mxSession the Matrix session to get data from.
|
||||
@param onComplete a block providing the newly created instance.
|
||||
*/
|
||||
+ (void)loadRoomDataSourceWithRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId andMatrixSession:(MXSession*)mxSession onComplete:(void (^)(id roomDataSource))onComplete;
|
||||
+ (void)loadRoomDataSourceWithRoomId:(NSString*)roomId
|
||||
initialEventId:(NSString*)initialEventId
|
||||
threadId:(NSString*)threadId
|
||||
andMatrixSession:(MXSession*)mxSession
|
||||
onComplete:(void (^)(id roomDataSource))onComplete;
|
||||
|
||||
/**
|
||||
Asynchronously create a data source to peek into a room.
|
||||
@@ -306,10 +316,14 @@ extern NSString *const kMXKRoomDataSourceTimelineErrorErrorKey;
|
||||
|
||||
@param roomId the id of the room to get data from.
|
||||
@param initialEventId the id of the event where to start the timeline.
|
||||
@param threadId the id of the thread to initialize. If provided, thread data source will be initialized from the room specified with `roomId`.
|
||||
@param mxSession the Matrix session to get data from.
|
||||
@return the newly created instance.
|
||||
*/
|
||||
- (instancetype)initWithRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId andMatrixSession:(MXSession*)mxSession;
|
||||
- (instancetype)initWithRoomId:(NSString*)roomId
|
||||
initialEventId:(NSString*)initialEventId
|
||||
threadId:(NSString*)threadId
|
||||
andMatrixSession:(MXSession*)mxSession;
|
||||
|
||||
/**
|
||||
Initialise the data source to peek into a room.
|
||||
@@ -697,6 +711,20 @@ extern NSString *const kMXKRoomDataSourceTimelineErrorErrorKey;
|
||||
*/
|
||||
+ (dispatch_queue_t)processingQueue;
|
||||
|
||||
/**
|
||||
Decides whether an event should be considered for asynchronous event processing.
|
||||
Default implementation checks for `filterMessagesWithURL` and undecryptable events sent before the user joined.
|
||||
Subclasses must call super at some point.
|
||||
|
||||
@param event event to be processed or not
|
||||
@param roomState the state of the room when the event fired
|
||||
@param direction the direction of the event
|
||||
@return YES to process the event, NO otherwise
|
||||
*/
|
||||
- (BOOL)shouldQueueEventForProcessing:(MXEvent*)event
|
||||
roomState:(MXRoomState*)roomState
|
||||
direction:(MXTimelineDirection)direction;
|
||||
|
||||
#pragma mark - Bubble collapsing
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
#import "MXKSendReplyEventStringLocalizer.h"
|
||||
#import "MXKSlashCommands.h"
|
||||
|
||||
const BOOL USE_THREAD_TIMELINE = NO;
|
||||
|
||||
#pragma mark - Constant definitions
|
||||
|
||||
@@ -201,9 +202,11 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
@property (nonatomic, assign) BOOL shouldStopBackPagination;
|
||||
|
||||
@property (nonatomic, readwrite) MXRoom *room;
|
||||
@property (nonatomic, readwrite) MXThread *thread;
|
||||
|
||||
@property (nonatomic, readwrite) MXRoom *secondaryRoom;
|
||||
@property (nonatomic, strong) MXEventTimeline *secondaryTimeline;
|
||||
@property (nonatomic, strong) id<MXEventTimeline> secondaryTimeline;
|
||||
@property (nonatomic, readwrite) NSString *threadId;
|
||||
|
||||
@end
|
||||
|
||||
@@ -215,9 +218,9 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
[self ensureSessionStateForDataSource:roomDataSource initialEventId:nil andMatrixSession:mxSession onComplete:onComplete];
|
||||
}
|
||||
|
||||
+ (void)loadRoomDataSourceWithRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId andMatrixSession:(MXSession*)mxSession onComplete:(void (^)(id roomDataSource))onComplete
|
||||
+ (void)loadRoomDataSourceWithRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId threadId:(NSString*)threadId andMatrixSession:(MXSession*)mxSession onComplete:(void (^)(id roomDataSource))onComplete
|
||||
{
|
||||
MXKRoomDataSource *roomDataSource = [[self alloc] initWithRoomId:roomId initialEventId:initialEventId andMatrixSession:mxSession];
|
||||
MXKRoomDataSource *roomDataSource = [[self alloc] initWithRoomId:roomId initialEventId:initialEventId threadId:threadId andMatrixSession:mxSession];
|
||||
[self ensureSessionStateForDataSource:roomDataSource initialEventId:initialEventId andMatrixSession:mxSession onComplete:onComplete];
|
||||
}
|
||||
|
||||
@@ -257,9 +260,31 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
|
||||
// Asynchronously preload data here so that the data will be ready later
|
||||
// to synchronously respond to that request
|
||||
[roomDataSource.room liveTimeline:^(MXEventTimeline *liveTimeline) {
|
||||
onComplete(roomDataSource);
|
||||
}];
|
||||
|
||||
if (USE_THREAD_TIMELINE)
|
||||
{
|
||||
if (roomDataSource.threadId)
|
||||
{
|
||||
[roomDataSource.thread liveTimeline:^(id<MXEventTimeline> _Nonnull liveTimeline) {
|
||||
[liveTimeline resetPagination];
|
||||
onComplete(roomDataSource);
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
[roomDataSource.room liveTimeline:^(id<MXEventTimeline> liveTimeline) {
|
||||
[liveTimeline resetPagination];
|
||||
onComplete(roomDataSource);
|
||||
}];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[roomDataSource.room liveTimeline:^(id<MXEventTimeline> liveTimeline) {
|
||||
[liveTimeline resetPagination];
|
||||
onComplete(roomDataSource);
|
||||
}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -347,7 +372,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId2 andMatrixSession:(MXSession*)mxSession
|
||||
- (instancetype)initWithRoomId:(NSString*)roomId initialEventId:(NSString*)initialEventId2 threadId:(NSString*)threadId andMatrixSession:(MXSession*)mxSession
|
||||
{
|
||||
self = [self initWithRoomId:roomId andMatrixSession:mxSession];
|
||||
if (self)
|
||||
@@ -357,6 +382,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
initialEventId = initialEventId2;
|
||||
_isLive = NO;
|
||||
}
|
||||
_threadId = threadId;
|
||||
}
|
||||
|
||||
return self;
|
||||
@@ -364,7 +390,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
|
||||
- (instancetype)initWithPeekingRoom:(MXPeekingRoom*)peekingRoom2 andInitialEventId:(NSString*)theInitialEventId
|
||||
{
|
||||
self = [self initWithRoomId:peekingRoom2.roomId initialEventId:theInitialEventId andMatrixSession:peekingRoom2.mxSession];
|
||||
self = [self initWithRoomId:peekingRoom2.roomId initialEventId:theInitialEventId threadId:nil andMatrixSession:peekingRoom2.mxSession];
|
||||
if (self)
|
||||
{
|
||||
peekingRoom = peekingRoom2;
|
||||
@@ -620,209 +646,318 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
{
|
||||
if (MXSessionStateStoreDataReady <= self.mxSession.state)
|
||||
{
|
||||
// Check whether the room is not already set
|
||||
if (!_room)
|
||||
if (USE_THREAD_TIMELINE)
|
||||
{
|
||||
// Are we peeking into a random room or displaying a room the user is part of?
|
||||
if (peekingRoom)
|
||||
if (_threadId)
|
||||
{
|
||||
self.room = peekingRoom;
|
||||
[self initializeTimelineForThread];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.room = [self.mxSession roomWithRoomId:_roomId];
|
||||
[self initializeTimelineForRoom];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
[self initializeTimelineForRoom];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_room)
|
||||
- (void)initializeTimelineForRoom
|
||||
{
|
||||
// Check whether the room is not already set
|
||||
if (!_room)
|
||||
{
|
||||
// Are we peeking into a random room or displaying a room the user is part of?
|
||||
if (peekingRoom)
|
||||
{
|
||||
self.room = peekingRoom;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.room = [self.mxSession roomWithRoomId:_roomId];
|
||||
}
|
||||
|
||||
if (_room)
|
||||
{
|
||||
// This is the time to set up the timeline according to the called init method
|
||||
if (_isLive)
|
||||
{
|
||||
// This is the time to set up the timeline according to the called init method
|
||||
if (_isLive)
|
||||
{
|
||||
// LIVE
|
||||
MXWeakify(self);
|
||||
[_room liveTimeline:^(MXEventTimeline *liveTimeline) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
// LIVE
|
||||
MXWeakify(self);
|
||||
[_room liveTimeline:^(id<MXEventTimeline> liveTimeline) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
self->_timeline = liveTimeline;
|
||||
self->_timeline = liveTimeline;
|
||||
|
||||
// Only one pagination process can be done at a time by an MXRoom object.
|
||||
// This assumption is satisfied by MatrixKit. Only MXRoomDataSource does it.
|
||||
[self.timeline resetPagination];
|
||||
// Only one pagination process can be done at a time by an MXRoom object.
|
||||
// This assumption is satisfied by MatrixKit. Only MXRoomDataSource does it.
|
||||
[self.timeline resetPagination];
|
||||
|
||||
// Observe room history flush (sync with limited timeline, or state event redaction)
|
||||
self->roomDidFlushDataNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXRoomDidFlushDataNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
// Observe room history flush (sync with limited timeline, or state event redaction)
|
||||
self->roomDidFlushDataNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kMXRoomDidFlushDataNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
||||
MXRoom *room = notif.object;
|
||||
if (self.mxSession == room.mxSession && ([self.roomId isEqualToString:room.roomId] ||
|
||||
([self.secondaryRoomId isEqualToString:room.roomId])))
|
||||
{
|
||||
// The existing room history has been flushed during server sync because a gap has been observed between local and server storage.
|
||||
[self reload];
|
||||
}
|
||||
|
||||
}];
|
||||
|
||||
// Add the event listeners, by considering all the event types (the event filtering is applying by the event formatter),
|
||||
// except if only the events with a url key in their content must be handled.
|
||||
[self refreshEventListeners:(self.filterMessagesWithURL ? @[kMXEventTypeStringRoomMessage] : [MXKAppSettings standardAppSettings].allEventTypesForMessages)];
|
||||
|
||||
// display typing notifications is optional
|
||||
// the inherited class can manage them by its own.
|
||||
if (self.showTypingNotifications)
|
||||
MXRoom *room = notif.object;
|
||||
if (self.mxSession == room.mxSession && ([self.roomId isEqualToString:room.roomId] ||
|
||||
([self.secondaryRoomId isEqualToString:room.roomId])))
|
||||
{
|
||||
// Register on typing notif
|
||||
[self listenTypingNotifications];
|
||||
// The existing room history has been flushed during server sync because a gap has been observed between local and server storage.
|
||||
[self reload];
|
||||
}
|
||||
|
||||
// Manage unsent messages
|
||||
[self handleUnsentMessages];
|
||||
|
||||
// Update here data source state if it is not already ready
|
||||
if (!self->_secondaryRoomId)
|
||||
{
|
||||
[self setState:MXKDataSourceStateReady];
|
||||
}
|
||||
|
||||
// Check user membership in this room
|
||||
MXMembership membership = self.room.summary.membership;
|
||||
if (membership == MXMembershipUnknown || membership == MXMembershipInvite)
|
||||
{
|
||||
// Here the initial sync is not ended or the room is a pending invitation.
|
||||
// Note: In case of invitation, a full sync will be triggered if the user joins this room.
|
||||
|
||||
// We have to observe here 'kMXRoomInitialSyncNotification' to reload room data when room sync is done.
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXRoomInitialSynced:) name:kMXRoomInitialSyncNotification object:self.room];
|
||||
}
|
||||
}];
|
||||
|
||||
if (!_secondaryRoom && _secondaryRoomId)
|
||||
|
||||
// Add the event listeners, by considering all the event types (the event filtering is applying by the event formatter),
|
||||
// except if only the events with a url key in their content must be handled.
|
||||
[self refreshEventListeners:(self.filterMessagesWithURL ? @[kMXEventTypeStringRoomMessage] : [MXKAppSettings standardAppSettings].allEventTypesForMessages)];
|
||||
|
||||
// display typing notifications is optional
|
||||
// the inherited class can manage them by its own.
|
||||
if (self.showTypingNotifications)
|
||||
{
|
||||
_secondaryRoom = [self.mxSession roomWithRoomId:_secondaryRoomId];
|
||||
|
||||
if (_secondaryRoom)
|
||||
{
|
||||
MXWeakify(self);
|
||||
[_secondaryRoom liveTimeline:^(MXEventTimeline *liveTimeline) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
// Register on typing notif
|
||||
[self listenTypingNotifications];
|
||||
}
|
||||
|
||||
self->_secondaryTimeline = liveTimeline;
|
||||
// Manage unsent messages
|
||||
[self handleUnsentMessages];
|
||||
|
||||
// Only one pagination process can be done at a time by an MXRoom object.
|
||||
// This assumption is satisfied by MatrixKit. Only MXRoomDataSource does it.
|
||||
[self.secondaryTimeline resetPagination];
|
||||
// Update here data source state if it is not already ready
|
||||
if (!self->_secondaryRoomId)
|
||||
{
|
||||
[self setState:MXKDataSourceStateReady];
|
||||
}
|
||||
|
||||
// Add the secondary event listeners, by considering the event types in self.secondaryRoomEventTypes
|
||||
[self refreshSecondaryEventListeners:self.secondaryRoomEventTypes];
|
||||
|
||||
// Update here data source state if it is not already ready
|
||||
[self setState:MXKDataSourceStateReady];
|
||||
// Check user membership in this room
|
||||
MXMembership membership = self.room.summary.membership;
|
||||
if (membership == MXMembershipUnknown || membership == MXMembershipInvite)
|
||||
{
|
||||
// Here the initial sync is not ended or the room is a pending invitation.
|
||||
// Note: In case of invitation, a full sync will be triggered if the user joins this room.
|
||||
|
||||
// Check user membership in the secondary room
|
||||
MXMembership membership = self.secondaryRoom.summary.membership;
|
||||
if (membership == MXMembershipUnknown || membership == MXMembershipInvite)
|
||||
{
|
||||
// Here the initial sync is not ended or the room is a pending invitation.
|
||||
// Note: In case of invitation, a full sync will be triggered if the user joins this room.
|
||||
// We have to observe here 'kMXRoomInitialSyncNotification' to reload room data when room sync is done.
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXRoomInitialSynced:) name:kMXRoomInitialSyncNotification object:self.room];
|
||||
}
|
||||
}];
|
||||
|
||||
if (!_secondaryRoom && _secondaryRoomId)
|
||||
{
|
||||
_secondaryRoom = [self.mxSession roomWithRoomId:_secondaryRoomId];
|
||||
|
||||
if (_secondaryRoom)
|
||||
{
|
||||
MXWeakify(self);
|
||||
[_secondaryRoom liveTimeline:^(id<MXEventTimeline> liveTimeline) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
// We have to observe here 'kMXRoomInitialSyncNotification' to reload room data when room sync is done.
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXRoomInitialSynced:) name:kMXRoomInitialSyncNotification object:self.secondaryRoom];
|
||||
}
|
||||
}];
|
||||
}
|
||||
self->_secondaryTimeline = liveTimeline;
|
||||
|
||||
// Only one pagination process can be done at a time by an MXRoom object.
|
||||
// This assumption is satisfied by MatrixKit. Only MXRoomDataSource does it.
|
||||
[self.secondaryTimeline resetPagination];
|
||||
|
||||
// Add the secondary event listeners, by considering the event types in self.secondaryRoomEventTypes
|
||||
[self refreshSecondaryEventListeners:self.secondaryRoomEventTypes];
|
||||
|
||||
// Update here data source state if it is not already ready
|
||||
[self setState:MXKDataSourceStateReady];
|
||||
|
||||
// Check user membership in the secondary room
|
||||
MXMembership membership = self.secondaryRoom.summary.membership;
|
||||
if (membership == MXMembershipUnknown || membership == MXMembershipInvite)
|
||||
{
|
||||
// Here the initial sync is not ended or the room is a pending invitation.
|
||||
// Note: In case of invitation, a full sync will be triggered if the user joins this room.
|
||||
|
||||
// We have to observe here 'kMXRoomInitialSyncNotification' to reload room data when room sync is done.
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXRoomInitialSynced:) name:kMXRoomInitialSyncNotification object:self.secondaryRoom];
|
||||
}
|
||||
}];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Past timeline
|
||||
// Less things need to configured
|
||||
_timeline = [_room timelineOnEvent:initialEventId];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Past timeline
|
||||
// Less things need to configured
|
||||
_timeline = [_room timelineOnEvent:initialEventId];
|
||||
|
||||
// Refresh the event listeners. Note: events for past timelines come only from pagination request
|
||||
[self refreshEventListeners:nil];
|
||||
// Refresh the event listeners. Note: events for past timelines come only from pagination request
|
||||
[self refreshEventListeners:nil];
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Preload the state and some messages around the initial event
|
||||
[_timeline resetPaginationAroundInitialEventWithLimit:_paginationLimitAroundInitialEvent success:^{
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
MXWeakify(self);
|
||||
// Do a "classic" reset. The room view controller will paginate
|
||||
// from the events stored in the timeline store
|
||||
[self.timeline resetPagination];
|
||||
|
||||
// Update here data source state if it is not already ready
|
||||
[self setState:MXKDataSourceStateReady];
|
||||
|
||||
// Preload the state and some messages around the initial event
|
||||
[_timeline resetPaginationAroundInitialEventWithLimit:_paginationLimitAroundInitialEvent success:^{
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
// Do a "classic" reset. The room view controller will paginate
|
||||
// from the events stored in the timeline store
|
||||
[self.timeline resetPagination];
|
||||
|
||||
// Update here data source state if it is not already ready
|
||||
[self setState:MXKDataSourceStateReady];
|
||||
MXLogDebug(@"[MXKRoomDataSource][%p] Failed to resetPaginationAroundInitialEventWithLimit", self);
|
||||
|
||||
// Notify the error
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKRoomDataSourceTimelineError
|
||||
object:self
|
||||
userInfo:@{
|
||||
kMXKRoomDataSourceTimelineErrorErrorKey: error
|
||||
}];
|
||||
}];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MXLogDebug(@"[MXKRoomDataSource][%p] Warning: The user does not know the room %@", self, _roomId);
|
||||
|
||||
// Update here data source state if it is not already ready
|
||||
[self setState:MXKDataSourceStateFailed];
|
||||
}
|
||||
}
|
||||
|
||||
if (_room && MXSessionStateRunning == self.mxSession.state)
|
||||
{
|
||||
// Flair handling: observe the update in the publicised groups by users when the flair is enabled in the room.
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidUpdatePublicisedGroupsForUsersNotification object:self.mxSession];
|
||||
[self.room state:^(MXRoomState *roomState) {
|
||||
if (roomState.relatedGroups.count)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXSessionUpdatePublicisedGroupsForUsers:) name:kMXSessionDidUpdatePublicisedGroupsForUsersNotification object:self.mxSession];
|
||||
|
||||
// Get a fresh profile for all the related groups. Trigger a table refresh when all requests are done.
|
||||
__block NSUInteger count = roomState.relatedGroups.count;
|
||||
for (NSString *groupId in roomState.relatedGroups)
|
||||
{
|
||||
MXGroup *group = [self.mxSession groupWithGroupId:groupId];
|
||||
if (!group)
|
||||
{
|
||||
// Create a group instance for the groups that the current user did not join.
|
||||
group = [[MXGroup alloc] initWithGroupId:groupId];
|
||||
[self->externalRelatedGroups setObject:group forKey:groupId];
|
||||
}
|
||||
|
||||
// Refresh the group profile from server.
|
||||
[self.mxSession updateGroupProfile:group success:^{
|
||||
|
||||
if (self.delegate && !(--count))
|
||||
{
|
||||
// All the requests have been done.
|
||||
[self.delegate dataSource:self didCellChange:nil];
|
||||
}
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
MXLogDebug(@"[MXKRoomDataSource][%p] Failed to resetPaginationAroundInitialEventWithLimit", self);
|
||||
MXLogDebug(@"[MXKRoomDataSource][%p] group profile update failed %@", self, groupId);
|
||||
|
||||
if (self.delegate && !(--count))
|
||||
{
|
||||
// All the requests have been done.
|
||||
[self.delegate dataSource:self didCellChange:nil];
|
||||
}
|
||||
|
||||
// Notify the error
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKRoomDataSourceTimelineError
|
||||
object:self
|
||||
userInfo:@{
|
||||
kMXKRoomDataSourceTimelineErrorErrorKey: error
|
||||
}];
|
||||
}];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MXLogDebug(@"[MXKRoomDataSource][%p] Warning: The user does not know the room %@", self, _roomId);
|
||||
|
||||
// Update here data source state if it is not already ready
|
||||
[self setState:MXKDataSourceStateFailed];
|
||||
}
|
||||
}
|
||||
|
||||
if (_room && MXSessionStateRunning == self.mxSession.state)
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)initializeTimelineForThread
|
||||
{
|
||||
// Check whether the thread is not already set
|
||||
if (_thread && self.state == MXKDataSourceStateReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_thread = [self.mxSession.threadingService threadWithId:_threadId];
|
||||
|
||||
if (!_thread)
|
||||
{
|
||||
// there is not a thread yet available, this will be a new thread
|
||||
_thread = [self.mxSession.threadingService createTempThreadWithId:_threadId roomId:_roomId];
|
||||
}
|
||||
|
||||
if (!_room)
|
||||
{
|
||||
// also hold a reference to the room
|
||||
_room = [self.mxSession roomWithRoomId:_roomId];
|
||||
}
|
||||
|
||||
if (_thread)
|
||||
{
|
||||
if (_isLive)
|
||||
{
|
||||
// Flair handling: observe the update in the publicised groups by users when the flair is enabled in the room.
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXSessionDidUpdatePublicisedGroupsForUsersNotification object:self.mxSession];
|
||||
[self.room state:^(MXRoomState *roomState) {
|
||||
if (roomState.relatedGroups.count)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didMXSessionUpdatePublicisedGroupsForUsers:) name:kMXSessionDidUpdatePublicisedGroupsForUsersNotification object:self.mxSession];
|
||||
|
||||
// Get a fresh profile for all the related groups. Trigger a table refresh when all requests are done.
|
||||
__block NSUInteger count = roomState.relatedGroups.count;
|
||||
for (NSString *groupId in roomState.relatedGroups)
|
||||
{
|
||||
MXGroup *group = [self.mxSession groupWithGroupId:groupId];
|
||||
if (!group)
|
||||
{
|
||||
// Create a group instance for the groups that the current user did not join.
|
||||
group = [[MXGroup alloc] initWithGroupId:groupId];
|
||||
[self->externalRelatedGroups setObject:group forKey:groupId];
|
||||
}
|
||||
|
||||
// Refresh the group profile from server.
|
||||
[self.mxSession updateGroupProfile:group success:^{
|
||||
|
||||
if (self.delegate && !(--count))
|
||||
{
|
||||
// All the requests have been done.
|
||||
[self.delegate dataSource:self didCellChange:nil];
|
||||
}
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
MXLogDebug(@"[MXKRoomDataSource][%p] group profile update failed %@", self, groupId);
|
||||
|
||||
if (self.delegate && !(--count))
|
||||
{
|
||||
// All the requests have been done.
|
||||
[self.delegate dataSource:self didCellChange:nil];
|
||||
}
|
||||
|
||||
}];
|
||||
}
|
||||
}
|
||||
[_thread liveTimeline:^(id<MXEventTimeline> _Nonnull liveTimeline) {
|
||||
self->_timeline = liveTimeline;
|
||||
|
||||
// Only one pagination process can be done at a time by an MXThread object.
|
||||
// This assumption is satisfied by MXRoomDataSource.
|
||||
[self.timeline resetPagination];
|
||||
|
||||
// Add the event listeners, by considering all the event types (the event filtering is applying by the event formatter),
|
||||
// except if only the events with a url key in their content must be handled.
|
||||
[self refreshEventListeners:(self.filterMessagesWithURL ? @[kMXEventTypeStringRoomMessage] : [MXKAppSettings standardAppSettings].allEventTypesForMessages)];
|
||||
|
||||
// Manage unsent messages
|
||||
[self handleUnsentMessages];
|
||||
|
||||
[self setState:MXKDataSourceStateReady];
|
||||
}];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Past timeline
|
||||
// Less things need to configured
|
||||
_timeline = [_thread timelineOnEvent:initialEventId];
|
||||
|
||||
// Refresh the event listeners. Note: events for past timelines come only from pagination request
|
||||
[self refreshEventListeners:nil];
|
||||
|
||||
MXWeakify(self);
|
||||
|
||||
// Preload the state and some messages around the initial event
|
||||
[_timeline resetPaginationAroundInitialEventWithLimit:_paginationLimitAroundInitialEvent success:^{
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
// Do a "classic" reset. The room view controller will paginate
|
||||
// from the events stored in the timeline store
|
||||
[self.timeline resetPagination];
|
||||
|
||||
// Update here data source state if it is not already ready
|
||||
[self setState:MXKDataSourceStateReady];
|
||||
|
||||
} failure:^(NSError *error) {
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
MXLogDebug(@"[MXKRoomDataSource][%p] Failed to resetPaginationAroundInitialEventWithLimit", self);
|
||||
|
||||
// Notify the error
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:kMXKRoomDataSourceTimelineError
|
||||
object:self
|
||||
userInfo:@{
|
||||
kMXKRoomDataSourceTimelineErrorErrorKey: error
|
||||
}];
|
||||
}];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MXLogDebug(@"[MXKRoomDataSource][%p] Warning: The user does not know the thread %@", self, _threadId);
|
||||
|
||||
// Update here data source state if it is not already ready
|
||||
[self setState:MXKDataSourceStateFailed];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1289,6 +1424,34 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
|
||||
}
|
||||
|
||||
- (BOOL)shouldQueueEventForProcessing:(MXEvent*)event roomState:(MXRoomState*)roomState direction:(MXTimelineDirection)direction
|
||||
{
|
||||
if (self.filterMessagesWithURL)
|
||||
{
|
||||
// Check whether the event has a value for the 'url' key in its content.
|
||||
if (!event.getMediaURLs.count)
|
||||
{
|
||||
// ignore the event
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for undecryptable messages that were sent while the user was not in the room and hide them
|
||||
if ([MXKAppSettings standardAppSettings].hidePreJoinedUndecryptableEvents
|
||||
&& direction == MXTimelineDirectionBackwards)
|
||||
{
|
||||
[self checkForPreJoinUTDWithEvent:event roomState:roomState];
|
||||
|
||||
// Hide pre joint UTD events
|
||||
if (self.shouldStopBackPagination)
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark - KVO
|
||||
|
||||
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
|
||||
@@ -1425,7 +1588,10 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
// Launch the pagination
|
||||
|
||||
MXWeakify(self);
|
||||
paginationRequest = [_timeline paginate:numItems direction:direction onlyFromStore:onlyFromStore complete:^{
|
||||
paginationRequest = [_timeline paginate:numItems
|
||||
direction:direction
|
||||
onlyFromStore:onlyFromStore
|
||||
complete:^{
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
@@ -1489,7 +1655,10 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
dispatch_group_enter(dispatchGroup);
|
||||
// Launch the pagination
|
||||
MXWeakify(self);
|
||||
secondaryPaginationRequest = [_secondaryTimeline paginate:numItems direction:direction onlyFromStore:onlyFromStore complete:^{
|
||||
secondaryPaginationRequest = [_secondaryTimeline paginate:numItems
|
||||
direction:direction
|
||||
onlyFromStore:onlyFromStore
|
||||
complete:^{
|
||||
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
@@ -1676,11 +1845,11 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
// Make the request to the homeserver
|
||||
if (isEmote)
|
||||
{
|
||||
[_room sendEmote:sanitizedText formattedText:html localEcho:&localEchoEvent success:success failure:failure];
|
||||
[_room sendEmote:sanitizedText formattedText:html threadId:self.threadId localEcho:&localEchoEvent success:success failure:failure];
|
||||
}
|
||||
else
|
||||
{
|
||||
[_room sendTextMessage:sanitizedText formattedText:html localEcho:&localEchoEvent success:success failure:failure];
|
||||
[_room sendTextMessage:sanitizedText formattedText:html threadId:self.threadId localEcho:&localEchoEvent success:success failure:failure];
|
||||
}
|
||||
|
||||
if (localEchoEvent)
|
||||
@@ -1821,7 +1990,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
{
|
||||
__block MXEvent *localEchoEvent = nil;
|
||||
|
||||
[_room sendImage:imageData withImageSize:imageSize mimeType:mimetype andThumbnail:thumbnail localEcho:&localEchoEvent success:success failure:failure];
|
||||
[_room sendImage:imageData withImageSize:imageSize mimeType:mimetype andThumbnail:thumbnail threadId:self.threadId localEcho:&localEchoEvent success:success failure:failure];
|
||||
|
||||
if (localEchoEvent)
|
||||
{
|
||||
@@ -1841,7 +2010,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
{
|
||||
__block MXEvent *localEchoEvent = nil;
|
||||
|
||||
[_room sendVideoAsset:videoAsset withThumbnail:videoThumbnail localEcho:&localEchoEvent success:success failure:failure];
|
||||
[_room sendVideoAsset:videoAsset withThumbnail:videoThumbnail threadId:self.threadId localEcho:&localEchoEvent success:success failure:failure];
|
||||
|
||||
if (localEchoEvent)
|
||||
{
|
||||
@@ -1855,7 +2024,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
{
|
||||
__block MXEvent *localEchoEvent = nil;
|
||||
|
||||
[_room sendAudioFile:audioFileLocalURL mimeType:mimeType localEcho:&localEchoEvent success:success failure:failure keepActualFilename:YES];
|
||||
[_room sendAudioFile:audioFileLocalURL mimeType:mimeType threadId:self.threadId localEcho:&localEchoEvent success:success failure:failure keepActualFilename:YES];
|
||||
|
||||
if (localEchoEvent)
|
||||
{
|
||||
@@ -1874,7 +2043,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
{
|
||||
__block MXEvent *localEchoEvent = nil;
|
||||
|
||||
[_room sendVoiceMessage:audioFileLocalURL mimeType:mimeType duration:duration samples:samples localEcho:&localEchoEvent success:success failure:failure keepActualFilename:YES];
|
||||
[_room sendVoiceMessage:audioFileLocalURL mimeType:mimeType duration:duration samples:samples threadId:self.threadId localEcho:&localEchoEvent success:success failure:failure keepActualFilename:YES];
|
||||
|
||||
if (localEchoEvent)
|
||||
{
|
||||
@@ -1889,7 +2058,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
{
|
||||
__block MXEvent *localEchoEvent = nil;
|
||||
|
||||
[_room sendFile:fileLocalURL mimeType:mimeType localEcho:&localEchoEvent success:success failure:failure];
|
||||
[_room sendFile:fileLocalURL mimeType:mimeType threadId:self.threadId localEcho:&localEchoEvent success:success failure:failure];
|
||||
|
||||
if (localEchoEvent)
|
||||
{
|
||||
@@ -1904,7 +2073,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
__block MXEvent *localEchoEvent = nil;
|
||||
|
||||
// Make the request to the homeserver
|
||||
[_room sendMessageWithContent:msgContent localEcho:&localEchoEvent success:success failure:failure];
|
||||
[_room sendMessageWithContent:msgContent threadId:self.threadId localEcho:&localEchoEvent success:success failure:failure];
|
||||
|
||||
if (localEchoEvent)
|
||||
{
|
||||
@@ -1926,6 +2095,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
[_room sendLocationWithLatitude:latitude
|
||||
longitude:longitude
|
||||
description:description
|
||||
threadId:self.threadId
|
||||
localEcho:&localEchoEvent
|
||||
success:success failure:failure];
|
||||
|
||||
@@ -1942,7 +2112,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
__block MXEvent *localEchoEvent = nil;
|
||||
|
||||
// Make the request to the homeserver
|
||||
[_room sendEventOfType:eventTypeString content:msgContent localEcho:&localEchoEvent success:success failure:failure];
|
||||
[_room sendEventOfType:eventTypeString content:msgContent threadId:self.threadId localEcho:&localEchoEvent success:success failure:failure];
|
||||
|
||||
if (localEchoEvent)
|
||||
{
|
||||
@@ -1969,7 +2139,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
{
|
||||
// We try here to resent an encrypted event
|
||||
// Note: we keep the existing local echo.
|
||||
[_room sendEventOfType:kMXEventTypeStringRoomEncrypted content:event.wireContent localEcho:&event success:success failure:failure];
|
||||
[_room sendEventOfType:kMXEventTypeStringRoomEncrypted content:event.wireContent threadId:self.threadId localEcho:&event success:success failure:failure];
|
||||
}
|
||||
else if ([event.type isEqualToString:kMXEventTypeStringRoomMessage])
|
||||
{
|
||||
@@ -1978,7 +2148,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
if ([msgType isEqualToString:kMXMessageTypeText] || [msgType isEqualToString:kMXMessageTypeEmote])
|
||||
{
|
||||
// Resend the Matrix event by reusing the existing echo
|
||||
[_room sendMessageWithContent:event.content localEcho:&event success:success failure:failure];
|
||||
[_room sendMessageWithContent:event.content threadId:self.threadId localEcho:&event success:success failure:failure];
|
||||
}
|
||||
else if ([msgType isEqualToString:kMXMessageTypeImage])
|
||||
{
|
||||
@@ -2021,7 +2191,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
else
|
||||
{
|
||||
// Resend the Matrix event by reusing the existing echo
|
||||
[_room sendMessageWithContent:event.content localEcho:&event success:success failure:failure];
|
||||
[_room sendMessageWithContent:event.content threadId:self.threadId localEcho:&event success:success failure:failure];
|
||||
}
|
||||
}
|
||||
else if ([msgType isEqualToString:kMXMessageTypeAudio])
|
||||
@@ -2032,7 +2202,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
if (!contentURL || ![contentURL hasPrefix:kMXMediaUploadIdPrefix])
|
||||
{
|
||||
// Resend the Matrix event by reusing the existing echo
|
||||
[_room sendMessageWithContent:event.content localEcho:&event success:success failure:failure];
|
||||
[_room sendMessageWithContent:event.content threadId:self.threadId localEcho:&event success:success failure:failure];
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2050,8 +2220,8 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
[self removeEventWithEventId:eventId];
|
||||
|
||||
if (event.isVoiceMessage) {
|
||||
NSNumber *duration = event.content[kMXMessageContentKeyExtensibleAudio][kMXMessageContentKeyExtensibleAudioDuration];
|
||||
NSArray<NSNumber *> *samples = event.content[kMXMessageContentKeyExtensibleAudio][kMXMessageContentKeyExtensibleAudioWaveform];
|
||||
NSNumber *duration = event.content[kMXMessageContentKeyExtensibleAudioMSC1767][kMXMessageContentKeyExtensibleAudioDuration];
|
||||
NSArray<NSNumber *> *samples = event.content[kMXMessageContentKeyExtensibleAudioMSC1767][kMXMessageContentKeyExtensibleAudioWaveform];
|
||||
|
||||
[self sendVoiceMessage:localFileURL mimeType:mimetype duration:duration.doubleValue samples:samples success:success failure:failure];
|
||||
} else {
|
||||
@@ -2072,7 +2242,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
else
|
||||
{
|
||||
// Resend the Matrix event by reusing the existing echo
|
||||
[_room sendMessageWithContent:event.content localEcho:&event success:success failure:failure];
|
||||
[_room sendMessageWithContent:event.content threadId:self.threadId localEcho:&event success:success failure:failure];
|
||||
}
|
||||
}
|
||||
else if ([msgType isEqualToString:kMXMessageTypeFile])
|
||||
@@ -2108,7 +2278,7 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
else
|
||||
{
|
||||
// Resend the Matrix event by reusing the existing echo
|
||||
[_room sendMessageWithContent:event.content localEcho:&event success:success failure:failure];
|
||||
[_room sendMessageWithContent:event.content threadId:self.threadId localEcho:&event success:success failure:failure];
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -2805,27 +2975,9 @@ typedef NS_ENUM (NSUInteger, MXKRoomDataSourceError) {
|
||||
MXLogVerbose(@"[MXKRoomDataSource][%p] queueEventForProcessing: %@", self, event.eventId);
|
||||
}
|
||||
|
||||
if (self.filterMessagesWithURL)
|
||||
if (![self shouldQueueEventForProcessing:event roomState:roomState direction:direction])
|
||||
{
|
||||
// Check whether the event has a value for the 'url' key in its content.
|
||||
if (!event.getMediaURLs.count)
|
||||
{
|
||||
// Ignore the event
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for undecryptable messages that were sent while the user was not in the room and hide them
|
||||
if ([MXKAppSettings standardAppSettings].hidePreJoinedUndecryptableEvents
|
||||
&& direction == MXTimelineDirectionBackwards)
|
||||
{
|
||||
[self checkForPreJoinUTDWithEvent:event roomState:roomState];
|
||||
|
||||
// Hide pre joint UTD events
|
||||
if (self.shouldStopBackPagination)
|
||||
{
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
MXKQueuedEvent *queuedEvent = [[MXKQueuedEvent alloc] initWithEvent:event andRoomState:roomState direction:direction];
|
||||
|
||||
@@ -85,7 +85,7 @@ NSString *const kMXKRoomMemberCellIdentifier = @"kMXKRoomMemberCellIdentifier";
|
||||
if (typingNotifListener)
|
||||
{
|
||||
MXWeakify(self);
|
||||
[mxRoom liveTimeline:^(MXEventTimeline *liveTimeline) {
|
||||
[mxRoom liveTimeline:^(id<MXEventTimeline> liveTimeline) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[liveTimeline removeListener:self->typingNotifListener];
|
||||
|
||||
@@ -325,11 +325,12 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=\"(.*?)\">([^<]*)</a>";
|
||||
|
||||
// Check first whether the event has been redacted
|
||||
NSString *redactedInfo = nil;
|
||||
BOOL isRedacted = (event.redactedBecause != nil);
|
||||
BOOL isRedacted = event.isRedactedEvent;
|
||||
if (isRedacted)
|
||||
{
|
||||
// Check whether redacted information is required
|
||||
if (_settings.showRedactionsInRoomHistory)
|
||||
// Check whether the event is a thread root or redacted information is required
|
||||
if ((RiotSettings.shared.enableThreads && [mxSession.threadingService isEventThreadRoot:event])
|
||||
|| _settings.showRedactionsInRoomHistory)
|
||||
{
|
||||
MXLogDebug(@"[MXKEventFormatter] Redacted event %@ (%@)", event.description, event.redactedBecause);
|
||||
|
||||
@@ -1252,7 +1253,7 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=\"(.*?)\">([^<]*)</a>";
|
||||
|
||||
NSString *body;
|
||||
BOOL isHTML = NO;
|
||||
NSString *eventThreadIdentifier = event.threadIdentifier;
|
||||
NSString *eventThreadId = event.threadId;
|
||||
|
||||
// Use the HTML formatted string if provided
|
||||
if ([event.content[@"format"] isEqualToString:kMXRoomMessageFormatHTML])
|
||||
@@ -1260,20 +1261,21 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=\"(.*?)\">([^<]*)</a>";
|
||||
isHTML =YES;
|
||||
MXJSONModelSetString(body, event.content[@"formatted_body"]);
|
||||
}
|
||||
else if (eventThreadIdentifier)
|
||||
else if (eventThreadId && !RiotSettings.shared.enableThreads)
|
||||
{
|
||||
NSString *repliedEventId = event.relatesTo.inReplyTo.eventId ?: eventThreadId;
|
||||
isHTML = YES;
|
||||
MXJSONModelSetString(body, event.content[kMXMessageBodyKey]);
|
||||
MXEvent *threadRootEvent = [mxSession.store eventWithEventId:eventThreadIdentifier
|
||||
inRoom:event.roomId];
|
||||
MXEvent *repliedEvent = [mxSession.store eventWithEventId:repliedEventId
|
||||
inRoom:event.roomId];
|
||||
|
||||
NSString *threadRootEventContent;
|
||||
MXJSONModelSetString(threadRootEventContent, threadRootEvent.content[kMXMessageBodyKey]);
|
||||
NSString *repliedEventContent;
|
||||
MXJSONModelSetString(repliedEventContent, repliedEvent.content[kMXMessageBodyKey]);
|
||||
body = [NSString stringWithFormat:@"<mx-reply><blockquote><a href=\"%@\">In reply to</a> <a href=\"%@\">%@</a><br>%@</blockquote></mx-reply>%@",
|
||||
[MXTools permalinkToEvent:eventThreadIdentifier inRoom:event.roomId],
|
||||
[MXTools permalinkToUserWithUserId:threadRootEvent.sender],
|
||||
threadRootEvent.sender,
|
||||
threadRootEventContent,
|
||||
[MXTools permalinkToEvent:repliedEventId inRoom:event.roomId],
|
||||
[MXTools permalinkToUserWithUserId:repliedEvent.sender],
|
||||
repliedEvent.sender,
|
||||
repliedEventContent,
|
||||
body];
|
||||
|
||||
}
|
||||
@@ -1359,9 +1361,7 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=\"(.*?)\">([^<]*)</a>";
|
||||
|
||||
// For replies, look for the end of the parent message
|
||||
// This helps us insert the emote prefix in the right place
|
||||
NSDictionary *relatesTo;
|
||||
MXJSONModelSetDictionary(relatesTo, event.content[@"m.relates_to"]);
|
||||
if ([relatesTo[@"m.in_reply_to"] isKindOfClass:NSDictionary.class] || event.isInThread)
|
||||
if (event.relatesTo.inReplyTo || (event.isInThread && !RiotSettings.shared.enableThreads))
|
||||
{
|
||||
[attributedDisplayText enumerateAttribute:kMXKToolsBlockquoteMarkAttribute
|
||||
inRange:NSMakeRange(0, attributedDisplayText.length)
|
||||
@@ -1577,6 +1577,11 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=\"(.*?)\">([^<]*)</a>";
|
||||
}
|
||||
case MXEventTypePollStart:
|
||||
{
|
||||
if (event.isEditEvent)
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
displayText = [MXEventContentPollStart modelFromJSON:event.content].question;
|
||||
break;
|
||||
}
|
||||
@@ -1699,7 +1704,7 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=\"(.*?)\">([^<]*)</a>";
|
||||
NSString *html = htmlString;
|
||||
|
||||
// Special treatment for "In reply to" message
|
||||
if (event.isReplyEvent || event.isInThread)
|
||||
if (event.isReplyEvent || (event.isInThread && !RiotSettings.shared.enableThreads))
|
||||
{
|
||||
html = [self renderReplyTo:html withRoomState:roomState];
|
||||
}
|
||||
@@ -2025,7 +2030,7 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=\"(.*?)\">([^<]*)</a>";
|
||||
textColor = _errorTextColor;
|
||||
}
|
||||
// Check whether the message is highlighted.
|
||||
else if (event.mxkIsHighlighted || (event.isInThread && ![event.sender isEqualToString:mxSession.myUserId]))
|
||||
else if (event.mxkIsHighlighted || (event.isInThread && !RiotSettings.shared.enableThreads && ![event.sender isEqualToString:mxSession.myUserId]))
|
||||
{
|
||||
textColor = _bingTextColor;
|
||||
}
|
||||
@@ -2089,7 +2094,7 @@ static NSString *const kHTMLATagRegexPattern = @"<a href=\"(.*?)\">([^<]*)</a>";
|
||||
{
|
||||
font = _callNoticesTextFont;
|
||||
}
|
||||
else if (event.mxkIsHighlighted || (event.isInThread && ![event.sender isEqualToString:mxSession.myUserId]))
|
||||
else if (event.mxkIsHighlighted || (event.isInThread && !RiotSettings.shared.enableThreads && ![event.sender isEqualToString:mxSession.myUserId]))
|
||||
{
|
||||
font = _bingTextFont;
|
||||
}
|
||||
|
||||
@@ -1,328 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKTableViewCell.h"
|
||||
#import "MXKCellRendering.h"
|
||||
#import "MXKReceiptSendersContainer.h"
|
||||
|
||||
#import <WebKit/WebKit.h>
|
||||
|
||||
@class MXKImageView;
|
||||
@class MXKPieChartView;
|
||||
@class MXKRoomBubbleCellData;
|
||||
|
||||
#pragma mark - MXKCellRenderingDelegate cell tap locations
|
||||
|
||||
/**
|
||||
Action identifier used when the user tapped on message text view.
|
||||
|
||||
The `userInfo` dictionary contains an `MXEvent` object under the `kMXKRoomBubbleCellEventKey` key, representing the tapped event.
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellTapOnMessageTextView;
|
||||
|
||||
/**
|
||||
Action identifier used when the user tapped on user name label.
|
||||
|
||||
The `userInfo` dictionary contains an `NSString` object under the `kMXKRoomBubbleCellUserIdKey` key, representing the user id of the tapped name label.
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellTapOnSenderNameLabel;
|
||||
|
||||
/**
|
||||
Action identifier used when the user tapped on avatar view.
|
||||
|
||||
The `userInfo` dictionary contains an `NSString` object under the `kMXKRoomBubbleCellUserIdKey` key, representing the user id of the tapped avatar.
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellTapOnAvatarView;
|
||||
|
||||
/**
|
||||
Action identifier used when the user tapped on date/time container.
|
||||
|
||||
The `userInfo` is nil.
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellTapOnDateTimeContainer;
|
||||
|
||||
/**
|
||||
Action identifier used when the user tapped on attachment view.
|
||||
|
||||
The `userInfo` is nil. The attachment can be retrieved via MXKRoomBubbleTableViewCell.attachmentView.
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellTapOnAttachmentView;
|
||||
|
||||
/**
|
||||
Action identifier used when the user tapped on overlay container.
|
||||
|
||||
The `userInfo` is nil
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellTapOnOverlayContainer;
|
||||
|
||||
/**
|
||||
Action identifier used when the user tapped on content view.
|
||||
|
||||
The `userInfo` dictionary may contain an `MXEvent` object under the `kMXKRoomBubbleCellEventKey` key, representing the event displayed at the level of the tapped line. This dictionary is empty if no event correspond to the tapped position.
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellTapOnContentView;
|
||||
|
||||
/**
|
||||
Action identifier used when the user pressed unsent button displayed in front of an unsent event.
|
||||
|
||||
The `userInfo` dictionary contains an `MXEvent` object under the `kMXKRoomBubbleCellEventKey` key, representing the unsent event.
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellUnsentButtonPressed;
|
||||
|
||||
/**
|
||||
Action identifier used when the user long pressed on a displayed event.
|
||||
|
||||
The `userInfo` dictionary contains an `MXEvent` object under the `kMXKRoomBubbleCellEventKey` key, representing the selected event.
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellLongPressOnEvent;
|
||||
|
||||
/**
|
||||
Action identifier used when the user long pressed on progress view.
|
||||
|
||||
The `userInfo` is nil. The progress view can be retrieved via MXKRoomBubbleTableViewCell.progressView.
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellLongPressOnProgressView;
|
||||
|
||||
/**
|
||||
Action identifier used when the user long pressed on avatar view.
|
||||
|
||||
The `userInfo` dictionary contains an `NSString` object under the `kMXKRoomBubbleCellUserIdKey` key, representing the user id of the concerned avatar.
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellLongPressOnAvatarView;
|
||||
|
||||
/**
|
||||
Action identifier used when the user clicked on a link.
|
||||
|
||||
This action is sent via the MXKCellRenderingDelegate `shouldDoAction` operation.
|
||||
|
||||
The `userInfo` dictionary contains a `NSURL` object under the `kMXKRoomBubbleCellUrl` key, representing the url the user wants to open. And a NSNumber wrapping `UITextItemInteraction` raw value, representing the type of interaction expected with the URL, under the `kMXKRoomBubbleCellUrlItemInteraction` key.
|
||||
|
||||
The shouldDoAction implementation must return NO to prevent the system (safari) from opening the link.
|
||||
|
||||
@discussion: If the link refers to a room alias/id, a user id or an event id, the non-ASCII characters (like '#' in room alias) has been
|
||||
escaped to be able to convert it into a legal URL string.
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellShouldInteractWithURL;
|
||||
|
||||
/**
|
||||
Notifications `userInfo` keys
|
||||
*/
|
||||
extern NSString *const kMXKRoomBubbleCellUserIdKey;
|
||||
extern NSString *const kMXKRoomBubbleCellEventKey;
|
||||
extern NSString *const kMXKRoomBubbleCellEventIdKey;
|
||||
extern NSString *const kMXKRoomBubbleCellReceiptsContainerKey;
|
||||
extern NSString *const kMXKRoomBubbleCellUrl;
|
||||
extern NSString *const kMXKRoomBubbleCellUrlItemInteraction;
|
||||
|
||||
#pragma mark - MXKRoomBubbleTableViewCell
|
||||
|
||||
/**
|
||||
`MXKRoomBubbleTableViewCell` is a base class for displaying a room bubble.
|
||||
|
||||
This class is used to handle a maximum of items which may be present in bubbles display (like the user's picture view, the message text view...).
|
||||
To optimize bubbles rendering, we advise to define a .xib for each kind of bubble layout (with or without sender's information, with or without attachment...).
|
||||
Each inherited class should define only the actual displayed items.
|
||||
*/
|
||||
@interface MXKRoomBubbleTableViewCell : MXKTableViewCell <MXKCellRendering, UITextViewDelegate, WKNavigationDelegate>
|
||||
{
|
||||
@protected
|
||||
/**
|
||||
The current bubble data displayed by the table view cell
|
||||
*/
|
||||
MXKRoomBubbleCellData *bubbleData;
|
||||
}
|
||||
|
||||
/**
|
||||
The current bubble data displayed by the table view cell
|
||||
*/
|
||||
@property (strong, nonatomic, readonly) MXKRoomBubbleCellData *bubbleData;
|
||||
|
||||
/**
|
||||
Option to highlight or not the content of message text view (May be used in case of text selection).
|
||||
NO by default.
|
||||
*/
|
||||
@property (nonatomic) BOOL allTextHighlighted;
|
||||
|
||||
/**
|
||||
Tell whether the animation should start automatically in case of animated gif (NO by default).
|
||||
*/
|
||||
@property (nonatomic) BOOL isAutoAnimatedGif;
|
||||
|
||||
/**
|
||||
The default picture displayed when no picture is available.
|
||||
*/
|
||||
@property (nonatomic) UIImage *picturePlaceholder;
|
||||
|
||||
/**
|
||||
The list of the temporary subviews that should be removed before reusing the cell (nil by default).
|
||||
*/
|
||||
@property (nonatomic) NSMutableArray<UIView*> *tmpSubviews;
|
||||
|
||||
/**
|
||||
The read receipts alignment.
|
||||
By default, they are left aligned.
|
||||
*/
|
||||
@property (nonatomic) ReadReceiptsAlignment readReceiptsAlignment;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UILabel *userNameLabel;
|
||||
@property (weak, nonatomic) IBOutlet UIView *userNameTapGestureMaskView;
|
||||
@property (strong, nonatomic) IBOutlet MXKImageView *pictureView;
|
||||
@property (weak, nonatomic) IBOutlet UITextView *messageTextView;
|
||||
@property (strong, nonatomic) IBOutlet MXKImageView *attachmentView;
|
||||
@property (strong, nonatomic) IBOutlet UIImageView *playIconView;
|
||||
@property (strong, nonatomic) IBOutlet UIImageView *fileTypeIconView;
|
||||
@property (weak, nonatomic) IBOutlet UIView *bubbleInfoContainer;
|
||||
@property (weak, nonatomic) IBOutlet UIView *bubbleOverlayContainer;
|
||||
|
||||
/**
|
||||
The container view in which the encryption information may be displayed
|
||||
*/
|
||||
@property (weak, nonatomic) IBOutlet UIView *encryptionStatusContainerView;
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIView *progressView;
|
||||
@property (weak, nonatomic) IBOutlet UILabel *statsLabel;
|
||||
@property (weak, nonatomic) IBOutlet MXKPieChartView *progressChartView;
|
||||
|
||||
/**
|
||||
The constraints which defines the relationship between messageTextView and its superview.
|
||||
The defined constant are supposed >= 0.
|
||||
*/
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *msgTextViewTopConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *msgTextViewBottomConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *msgTextViewLeadingConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *msgTextViewTrailingConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *msgTextViewWidthConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *msgTextViewMinHeightConstraint;
|
||||
|
||||
/**
|
||||
The constraints which defines the relationship between attachmentView and its superview
|
||||
The defined constant are supposed >= 0.
|
||||
*/
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *attachViewWidthConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *attachViewMinHeightConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *attachViewTopConstraint;
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *attachViewBottomConstraint;
|
||||
|
||||
/**
|
||||
The constraints which defines the relationship between bubbleInfoContainer and its superview
|
||||
The defined constant are supposed >= 0.
|
||||
*/
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bubbleInfoContainerTopConstraint;
|
||||
|
||||
/**
|
||||
The read marker view and its layout constraints (nil by default).
|
||||
*/
|
||||
@property (nonatomic) UIView *readMarkerView;
|
||||
@property (nonatomic) NSLayoutConstraint *readMarkerViewTopConstraint;
|
||||
@property (nonatomic) NSLayoutConstraint *readMarkerViewLeadingConstraint;
|
||||
@property (nonatomic) NSLayoutConstraint *readMarkerViewTrailingConstraint;
|
||||
@property (nonatomic) NSLayoutConstraint *readMarkerViewHeightConstraint;
|
||||
|
||||
/**
|
||||
The potential webview used to render an attachment (for example an animated gif).
|
||||
*/
|
||||
@property (nonatomic) WKWebView *attachmentWebView;
|
||||
|
||||
/**
|
||||
Called during the designated initializer of the UITableViewCell class to set the default
|
||||
properties values.
|
||||
|
||||
You should not call this method directly.
|
||||
|
||||
Subclasses can override this method as needed to customize the initialization.
|
||||
*/
|
||||
- (void)finalizeInit;
|
||||
|
||||
/**
|
||||
Handle progressView display.
|
||||
*/
|
||||
- (void)startProgressUI;
|
||||
- (void)updateProgressUI:(NSDictionary*)statisticsDict;
|
||||
|
||||
#pragma mark - Original Xib values
|
||||
|
||||
/**
|
||||
Get an original instance of the `MXKRoomBubbleTableViewCell` child class.
|
||||
|
||||
@return an instance of the child class caller which has the original Xib values.
|
||||
*/
|
||||
+ (MXKRoomBubbleTableViewCell*)cellWithOriginalXib;
|
||||
|
||||
/**
|
||||
Disable the handling of the long press on event (see kMXKRoomBubbleCellLongPressOnEvent). NO by default.
|
||||
|
||||
CAUTION: Changing this flag only impact the new created cells (existing 'MXKRoomBubbleTableViewCell' instances are unchanged).
|
||||
*/
|
||||
+ (void)disableLongPressGestureOnEvent:(BOOL)disable;
|
||||
|
||||
/**
|
||||
Method used during [MXKCellRendering render:] to check the provided `cellData`
|
||||
and prepare the protected `bubbleData`.
|
||||
Do not override it.
|
||||
|
||||
@param cellData the data object to render.
|
||||
*/
|
||||
- (void)prepareRender:(MXKCellData*)cellData;
|
||||
|
||||
/**
|
||||
Refresh the flair information added to the sender display name.
|
||||
*/
|
||||
- (void)renderSenderFlair;
|
||||
|
||||
/**
|
||||
Highlight text message related to a specific event in the displayed message.
|
||||
|
||||
@param eventId the id of the event to highlight (use nil to cancel highlighting).
|
||||
*/
|
||||
- (void)highlightTextMessageForEvent:(NSString*)eventId;
|
||||
|
||||
/**
|
||||
The top position of an event in the cell.
|
||||
|
||||
A cell can display several events. The method returns the vertical position of a given
|
||||
event in the cell.
|
||||
|
||||
@return the y position (in pixel) of the event in the cell.
|
||||
*/
|
||||
- (CGFloat)topPositionOfEvent:(NSString*)eventId;
|
||||
|
||||
/**
|
||||
The bottom position of an event in the cell.
|
||||
|
||||
A cell can display several events. The method returns the vertical position of the bottom part
|
||||
of a given event in the cell.
|
||||
|
||||
@return the y position (in pixel) of the bottom part of the event in the cell.
|
||||
*/
|
||||
- (CGFloat)bottomPositionOfEvent:(NSString*)eventId;
|
||||
|
||||
/**
|
||||
Restore `attachViewBottomConstraint` constant to default value.
|
||||
*/
|
||||
- (void)resetAttachmentViewBottomConstraintConstant;
|
||||
|
||||
/**
|
||||
Redeclare heightForCellData:withMaximumWidth: method from MXKCellRendering to use it as a class method in Swift and not a static method.
|
||||
*/
|
||||
+ (CGFloat)heightForCellData:(MXKCellData*)cellData withMaximumWidth:(CGFloat)maxWidth;
|
||||
|
||||
/**
|
||||
Setup outlets views. Useful to call when cell subclass does not use a xib otherwise this method is called automatically in `awakeFromNib`.
|
||||
*/
|
||||
- (void)setupViews;
|
||||
|
||||
@end
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,25 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomBubbleTableViewCell.h"
|
||||
|
||||
/**
|
||||
`MXKRoomEmptyBubbleTableViewCell` displays an empty bubbles without user's information.
|
||||
This kind of bubble may be used to localize an event without display in the room history.
|
||||
*/
|
||||
@interface MXKRoomEmptyBubbleTableViewCell : MXKRoomBubbleTableViewCell
|
||||
|
||||
@end
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomEmptyBubbleTableViewCell.h"
|
||||
|
||||
@implementation MXKRoomEmptyBubbleTableViewCell
|
||||
|
||||
@end
|
||||
@@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="pad-g3-2YJ" customClass="MXKRoomEmptyBubbleTableViewCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="8"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="pad-g3-2YJ" id="fCg-ju-gnG">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="7"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</tableViewCellContentView>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKTableViewCell.h"
|
||||
|
||||
#import "MXKCellRendering.h"
|
||||
|
||||
/**
|
||||
`MXKRoomIOSBubbleTableViewCell` instances mimic bubbles in the stock iOS messages application.
|
||||
*/
|
||||
@interface MXKRoomIOSBubbleTableViewCell : MXKTableViewCell <MXKCellRendering>
|
||||
|
||||
@end
|
||||
@@ -1,45 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomIOSBubbleTableViewCell.h"
|
||||
|
||||
#import "MXKRoomBubbleCellDataStoring.h"
|
||||
|
||||
@implementation MXKRoomIOSBubbleTableViewCell
|
||||
|
||||
- (void)render:(MXKCellData *)cellData
|
||||
{
|
||||
id<MXKRoomBubbleCellDataStoring> bubbleData = (id<MXKRoomBubbleCellDataStoring>)cellData;
|
||||
if (bubbleData)
|
||||
{
|
||||
self.textLabel.attributedText = bubbleData.attributedTextMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
self.textLabel.text = @"";
|
||||
}
|
||||
|
||||
// Light custo for now... @TODO
|
||||
self.layer.cornerRadius = 20;
|
||||
self.backgroundColor = [UIColor blueColor];
|
||||
}
|
||||
|
||||
+ (CGFloat)heightForCellData:(MXKCellData *)cellData withMaximumWidth:(CGFloat)maxWidth
|
||||
{
|
||||
return 44;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,36 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomOutgoingBubbleTableViewCell.h"
|
||||
|
||||
/**
|
||||
`MXKRoomIOSBubbleTableViewCell` instances mimic bubbles in the stock iOS messages application.
|
||||
It is dedicated to outgoing messages.
|
||||
It subclasses `MXKRoomOutgoingBubbleTableViewCell` to take benefit of the available mechanic.
|
||||
*/
|
||||
@interface MXKRoomIOSOutgoingBubbleTableViewCell : MXKRoomOutgoingBubbleTableViewCell
|
||||
|
||||
/**
|
||||
The green bubble displayed in background.
|
||||
*/
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *bubbleImageView;
|
||||
|
||||
/**
|
||||
The width constraint on this backgroung green bubble.
|
||||
*/
|
||||
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *bubbleImageViewWidthConstraint;
|
||||
|
||||
@end
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomIOSOutgoingBubbleTableViewCell.h"
|
||||
|
||||
#import "MXKRoomBubbleCellData.h"
|
||||
|
||||
#import "MXEvent+MatrixKit.h"
|
||||
#import "MXKTools.h"
|
||||
|
||||
#import "NSBundle+MatrixKit.h"
|
||||
|
||||
#import "MXKImageView.h"
|
||||
|
||||
#define OUTGOING_BUBBLE_COLOR 0x00e34d
|
||||
|
||||
@implementation MXKRoomIOSOutgoingBubbleTableViewCell
|
||||
|
||||
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
|
||||
{
|
||||
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
|
||||
if (self)
|
||||
{
|
||||
// Create the strechable background bubble
|
||||
self.bubbleImageView.image = self.class.bubbleImage;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)layoutSubviews
|
||||
{
|
||||
[super layoutSubviews];
|
||||
}
|
||||
|
||||
- (void)render:(MXKCellData *)cellData
|
||||
{
|
||||
[super render:cellData];
|
||||
|
||||
// Reset values
|
||||
self.bubbleImageView.hidden = NO;
|
||||
|
||||
// Customise the data precomputed by the legacy classes
|
||||
// Replace black color in texts by the white color expected for outgoing messages.
|
||||
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:self.messageTextView.attributedText];
|
||||
|
||||
// Change all attributes one by one
|
||||
[attributedString enumerateAttributesInRange:NSMakeRange(0, attributedString.length) options:0 usingBlock:^(NSDictionary *attrs, NSRange range, BOOL *stop)
|
||||
{
|
||||
|
||||
// Replace only black colored texts
|
||||
if (attrs[NSForegroundColorAttributeName] == self->bubbleData.eventFormatter.defaultTextColor)
|
||||
{
|
||||
|
||||
// By white
|
||||
NSMutableDictionary *newAttrs = [NSMutableDictionary dictionaryWithDictionary:attrs];
|
||||
newAttrs[NSForegroundColorAttributeName] = [UIColor whiteColor];
|
||||
|
||||
[attributedString setAttributes:newAttrs range:range];
|
||||
}
|
||||
}];
|
||||
|
||||
self.messageTextView.attributedText = attributedString;
|
||||
|
||||
// Update the bubble width to include the text view
|
||||
self.bubbleImageViewWidthConstraint.constant = bubbleData.contentSize.width + 17;
|
||||
|
||||
// Limit bubble width
|
||||
if (self.bubbleImageViewWidthConstraint.constant < 46)
|
||||
{
|
||||
self.bubbleImageViewWidthConstraint.constant = 46;
|
||||
}
|
||||
|
||||
// Mask the image with the bubble
|
||||
if (bubbleData.attachment && bubbleData.attachment.type != MXKAttachmentTypeFile && bubbleData.attachment.type != MXKAttachmentTypeAudio)
|
||||
{
|
||||
self.bubbleImageView.hidden = YES;
|
||||
|
||||
UIImageView *rightBubbleImageView = [[UIImageView alloc] initWithImage:self.class.bubbleImage];
|
||||
rightBubbleImageView.frame = CGRectMake(0, 0, self.bubbleImageViewWidthConstraint.constant, bubbleData.contentSize.height + self.attachViewTopConstraint.constant - 4);
|
||||
|
||||
self.attachmentView.layer.mask = rightBubbleImageView.layer;
|
||||
}
|
||||
}
|
||||
|
||||
+ (CGFloat)heightForCellData:(MXKCellData *)cellData withMaximumWidth:(CGFloat)maxWidth
|
||||
{
|
||||
CGFloat rowHeight = [super heightForCellData:cellData withMaximumWidth:maxWidth];
|
||||
|
||||
CGFloat height = self.cellWithOriginalXib.frame.size.height;
|
||||
|
||||
// Use the xib height as the minimal height
|
||||
if (rowHeight < height)
|
||||
{
|
||||
rowHeight = height;
|
||||
}
|
||||
|
||||
return rowHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
Create the strechable background bubble.
|
||||
|
||||
@return the bubble image.
|
||||
*/
|
||||
+ (UIImage *)bubbleImage
|
||||
{
|
||||
UIImage *rightBubbleImage = [NSBundle mxk_imageFromMXKAssetsBundleWithName:@"bubble_ios_messages_right"];
|
||||
|
||||
rightBubbleImage = [MXKTools paintImage:rightBubbleImage
|
||||
withColor:[MXKTools colorWithRGBValue:OUTGOING_BUBBLE_COLOR]];
|
||||
|
||||
UIEdgeInsets edgeInsets = UIEdgeInsetsMake(17, 22, 17, 27);
|
||||
return [rightBubbleImage resizableImageWithCapInsets:edgeInsets];
|
||||
}
|
||||
|
||||
@end
|
||||
-161
@@ -1,161 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
|
||||
<capability name="Constraints to layout margins" minToolsVersion="6.0"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="pad-g3-2YJ" customClass="MXKRoomIOSOutgoingBubbleTableViewCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="40"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="pad-g3-2YJ" id="fCg-ju-gnG">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="39"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Ktd-ms-tAu" userLabel="Bubble Image View">
|
||||
<rect key="frame" x="160" y="2" width="422" height="35"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="422" id="ptG-QV-Cix"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" text="text message" translatesAutoresizingMaskIntoConstraints="NO" id="tgO-Rv-C7R">
|
||||
<rect key="frame" x="74" y="3" width="495" height="36"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
<dataDetectorType key="dataDetectorTypes" link="YES"/>
|
||||
</textView>
|
||||
<view contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="SIW-l4-PfI" userLabel="Attachment View" customClass="MXKImageView">
|
||||
<rect key="frame" x="160" y="2" width="422" height="35"/>
|
||||
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="192" id="iGr-e7-bde"/>
|
||||
</constraints>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="iGr-e7-bde"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</view>
|
||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ZC1-hT-7fs">
|
||||
<rect key="frame" x="355" y="4" width="32" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="32" id="MOQ-Xi-18w"/>
|
||||
<constraint firstAttribute="height" constant="32" id="pGM-pf-SiP"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="Mqf-7a-bsm">
|
||||
<rect key="frame" x="361" y="10" width="20" height="20"/>
|
||||
</activityIndicatorView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LVJ-Av-zVs" userLabel="showHideDateTime">
|
||||
<rect key="frame" x="0.0" y="0.0" width="74" height="39"/>
|
||||
<state key="normal">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="showHideDateTime:" destination="pad-g3-2YJ" eventType="touchUpInside" id="Ztw-z5-zlU"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a51-cR-7FE" userLabel="bubbleInfoContainer">
|
||||
<rect key="frame" x="8" y="10" width="66" height="29"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="apW-hM-veR" userLabel="ProgressView">
|
||||
<rect key="frame" x="18" y="-16" width="100" height="71"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="text" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" minimumFontSize="4" preferredMaxLayoutWidth="100" translatesAutoresizingMaskIntoConstraints="NO" id="DYj-Mb-me4" userLabel="Progress stats">
|
||||
<rect key="frame" x="0.0" y="61" width="100" height="10"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="8"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Oec-kb-Tsz" customClass="MXKPieChartView">
|
||||
<rect key="frame" x="30" y="0.0" width="40" height="41"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="40" id="6tZ-ag-7TT"/>
|
||||
<constraint firstAttribute="width" constant="40" id="duC-38-cLC"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<gestureRecognizers/>
|
||||
<constraints>
|
||||
<constraint firstItem="Oec-kb-Tsz" firstAttribute="top" secondItem="apW-hM-veR" secondAttribute="top" id="49H-ch-qkC"/>
|
||||
<constraint firstAttribute="height" constant="70" id="GhG-zB-k3A"/>
|
||||
<constraint firstAttribute="centerX" secondItem="Oec-kb-Tsz" secondAttribute="centerX" id="KZy-2p-KaW"/>
|
||||
<constraint firstItem="DYj-Mb-me4" firstAttribute="leading" secondItem="apW-hM-veR" secondAttribute="leading" id="UxL-bV-5Ca"/>
|
||||
<constraint firstAttribute="bottom" secondItem="DYj-Mb-me4" secondAttribute="bottom" id="YFp-gQ-NFz"/>
|
||||
<constraint firstAttribute="width" constant="100" id="Zr4-5T-h9g"/>
|
||||
<constraint firstAttribute="trailing" secondItem="DYj-Mb-me4" secondAttribute="trailing" id="ehN-ME-1U1"/>
|
||||
<constraint firstAttribute="centerX" secondItem="DYj-Mb-me4" secondAttribute="centerX" id="nuq-lO-8pT"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="centerX" secondItem="Mqf-7a-bsm" secondAttribute="centerX" id="1b6-1l-hg0"/>
|
||||
<constraint firstItem="tgO-Rv-C7R" firstAttribute="leading" secondItem="LVJ-Av-zVs" secondAttribute="trailing" id="45B-ph-Sc3"/>
|
||||
<constraint firstAttribute="bottom" secondItem="tgO-Rv-C7R" secondAttribute="bottom" id="7C3-Tl-mMq"/>
|
||||
<constraint firstItem="tgO-Rv-C7R" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" constant="3" id="8Sy-eu-tYs"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="width" secondItem="Ktd-ms-tAu" secondAttribute="width" id="AjE-jd-r7q"/>
|
||||
<constraint firstAttribute="trailing" secondItem="SIW-l4-PfI" secondAttribute="trailing" constant="8" id="D8p-mV-ytb"/>
|
||||
<constraint firstItem="a51-cR-7FE" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" constant="8" id="E3x-h8-GPF"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="bottom" secondItem="Ktd-ms-tAu" secondAttribute="bottom" id="ET2-rD-uVQ"/>
|
||||
<constraint firstItem="LVJ-Av-zVs" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" id="Hve-E3-z5N"/>
|
||||
<constraint firstAttribute="bottom" secondItem="LVJ-Av-zVs" secondAttribute="bottom" id="IKr-Dc-HKz"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="Ktd-ms-tAu" secondAttribute="trailing" constant="10" id="LEJ-mA-aF4"/>
|
||||
<constraint firstItem="apW-hM-veR" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" constant="18" id="LFn-vp-m0v"/>
|
||||
<constraint firstItem="tgO-Rv-C7R" firstAttribute="leading" secondItem="a51-cR-7FE" secondAttribute="trailing" id="PJ9-Px-DPH"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" constant="18" id="QDm-tP-KWa"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="top" secondItem="Ktd-ms-tAu" secondAttribute="top" id="W0E-eV-LGg"/>
|
||||
<constraint firstAttribute="bottom" secondItem="SIW-l4-PfI" secondAttribute="bottom" id="fMN-Th-SOT"/>
|
||||
<constraint firstItem="a51-cR-7FE" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" constant="10" id="fQv-07-Pgx"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="centerY" secondItem="ZC1-hT-7fs" secondAttribute="centerY" id="ffI-vh-SW3"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Ktd-ms-tAu" secondAttribute="bottom" constant="2" id="haQ-G8-eZD"/>
|
||||
<constraint firstItem="tgO-Rv-C7R" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" constant="74" id="hwr-aa-TB4"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="centerX" secondItem="ZC1-hT-7fs" secondAttribute="centerX" id="jah-TA-P0P"/>
|
||||
<constraint firstItem="Ktd-ms-tAu" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" constant="2" id="ltB-ic-svk"/>
|
||||
<constraint firstItem="LVJ-Av-zVs" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" id="pYO-hi-P72"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="centerY" secondItem="Mqf-7a-bsm" secondAttribute="centerY" id="sKJ-ny-LjM"/>
|
||||
<constraint firstAttribute="bottom" secondItem="a51-cR-7FE" secondAttribute="bottom" id="viZ-Sx-3RW"/>
|
||||
<constraint firstItem="apW-hM-veR" firstAttribute="centerY" secondItem="SIW-l4-PfI" secondAttribute="centerY" id="wmh-x1-U32"/>
|
||||
<constraint firstAttribute="trailing" secondItem="tgO-Rv-C7R" secondAttribute="trailing" constant="31" id="xYz-lp-c7K"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="leading" secondItem="Ktd-ms-tAu" secondAttribute="leading" id="zvi-c3-uqP"/>
|
||||
</constraints>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="D8p-mV-ytb"/>
|
||||
<exclude reference="QDm-tP-KWa"/>
|
||||
<exclude reference="fMN-Th-SOT"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</tableViewCellContentView>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="activityIndicator" destination="Mqf-7a-bsm" id="toi-nL-eJa"/>
|
||||
<outlet property="attachViewTopConstraint" destination="QDm-tP-KWa" id="Ku6-FC-jqo"/>
|
||||
<outlet property="attachViewWidthConstraint" destination="iGr-e7-bde" id="uD4-aU-1Ru"/>
|
||||
<outlet property="attachmentView" destination="SIW-l4-PfI" id="L4H-ub-pPI"/>
|
||||
<outlet property="bubbleImageView" destination="Ktd-ms-tAu" id="I0r-5F-rhe"/>
|
||||
<outlet property="bubbleImageViewWidthConstraint" destination="ptG-QV-Cix" id="TUH-dw-uqF"/>
|
||||
<outlet property="bubbleInfoContainer" destination="a51-cR-7FE" id="wrR-cU-DVm"/>
|
||||
<outlet property="bubbleInfoContainerTopConstraint" destination="fQv-07-Pgx" id="82c-KH-Wop"/>
|
||||
<outlet property="messageTextView" destination="tgO-Rv-C7R" id="LZ5-hQ-AbQ"/>
|
||||
<outlet property="msgTextViewBottomConstraint" destination="7C3-Tl-mMq" id="5Ff-xL-G1i"/>
|
||||
<outlet property="msgTextViewLeadingConstraint" destination="hwr-aa-TB4" id="A1E-ap-Ug6"/>
|
||||
<outlet property="msgTextViewTopConstraint" destination="8Sy-eu-tYs" id="7yx-oJ-KBP"/>
|
||||
<outlet property="msgTextViewTrailingConstraint" destination="xYz-lp-c7K" id="hc2-Cg-is4"/>
|
||||
<outlet property="playIconView" destination="ZC1-hT-7fs" id="zeH-8B-gxw"/>
|
||||
<outlet property="progressChartView" destination="Oec-kb-Tsz" id="uoq-6v-6Tm"/>
|
||||
<outlet property="progressView" destination="apW-hM-veR" id="Iy8-ca-hMi"/>
|
||||
<outlet property="statsLabel" destination="DYj-Mb-me4" id="CbG-5V-unO"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomIncomingBubbleTableViewCell.h"
|
||||
|
||||
/**
|
||||
`MXKRoomIncomingAttachmentBubbleCell` displays incoming attachment bubbles with sender's information.
|
||||
*/
|
||||
@interface MXKRoomIncomingAttachmentBubbleCell : MXKRoomIncomingBubbleTableViewCell
|
||||
|
||||
@end
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomIncomingAttachmentBubbleCell.h"
|
||||
|
||||
@implementation MXKRoomIncomingAttachmentBubbleCell
|
||||
|
||||
@end
|
||||
@@ -1,171 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="WmY-Jw-mqv" customClass="MXKRoomIncomingAttachmentBubbleCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WmY-Jw-mqv" id="ef1-Tq-U3Z">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="49"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleAspectFill" translatesAutoresizingMaskIntoConstraints="NO" id="hgp-Z5-rAj" userLabel="Picture View" customClass="MXKImageView">
|
||||
<rect key="frame" x="8" y="5" width="40" height="40"/>
|
||||
<color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="40" id="NQk-ck-Lo8"/>
|
||||
<constraint firstAttribute="height" constant="40" id="dNT-QU-CUG"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="zwq-eh-8Fb" userLabel="typingBadge">
|
||||
<rect key="frame" x="5" y="0.0" width="20" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="20" id="7ni-rb-ovL"/>
|
||||
<constraint firstAttribute="height" constant="20" id="mcu-rQ-hnj"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="User name:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="q9c-0p-QyP">
|
||||
<rect key="frame" x="51" y="3" width="480" height="20"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="20" placeholder="YES" id="5ZO-W1-tS2"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="5IE-JS-uf3" userLabel="Attachment View" customClass="MXKImageView">
|
||||
<rect key="frame" x="51" y="18" width="192" height="23"/>
|
||||
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="192" id="9zO-jU-qTb"/>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="23" id="C5F-6D-LZx"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="K9X-gn-noF" userLabel="File Type Image View">
|
||||
<rect key="frame" x="51" y="18" width="32" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="32" id="OE8-oh-B7Q"/>
|
||||
<constraint firstAttribute="height" constant="32" id="jJB-zj-fbT"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Cot-3X-2cU" userLabel="Play Icon Image View">
|
||||
<rect key="frame" x="131" y="14" width="32" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="32" id="8io-Wk-GzF"/>
|
||||
<constraint firstAttribute="width" constant="32" id="aeJ-j3-rfX"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kwd-hP-feC" userLabel="showHideDateTime">
|
||||
<rect key="frame" x="531" y="0.0" width="69" height="49"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="69" id="9vA-4g-EE5"/>
|
||||
</constraints>
|
||||
<state key="normal">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="showHideDateTime:" destination="WmY-Jw-mqv" eventType="touchUpInside" id="jYV-nj-p60"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IOg-Kt-8vW" userLabel="bubbleInfoContainer">
|
||||
<rect key="frame" x="531" y="18" width="61" height="31"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="61" id="tLr-6k-ArA"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fdx-qs-8en" userLabel="ProgressView">
|
||||
<rect key="frame" x="487" y="-5" width="100" height="70"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="rate" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" minimumFontSize="4" preferredMaxLayoutWidth="100" translatesAutoresizingMaskIntoConstraints="NO" id="eU5-iK-u8i" userLabel="Progress stats">
|
||||
<rect key="frame" x="0.0" y="60" width="100" height="10"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="8"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hJj-TC-pxK" customClass="MXKPieChartView">
|
||||
<rect key="frame" x="30" y="0.0" width="40" height="40"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="40" id="Cpt-s4-tlK"/>
|
||||
<constraint firstAttribute="height" constant="40" id="Jb4-9E-tG0"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<gestureRecognizers/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="70" id="5w2-Hm-hZx"/>
|
||||
<constraint firstAttribute="centerX" secondItem="eU5-iK-u8i" secondAttribute="centerX" id="APi-aE-mLc"/>
|
||||
<constraint firstItem="eU5-iK-u8i" firstAttribute="leading" secondItem="fdx-qs-8en" secondAttribute="leading" id="Njw-3a-E9Y"/>
|
||||
<constraint firstAttribute="bottom" secondItem="eU5-iK-u8i" secondAttribute="bottom" id="QMO-g9-QVE"/>
|
||||
<constraint firstAttribute="centerX" secondItem="hJj-TC-pxK" secondAttribute="centerX" id="laR-Vg-ol3"/>
|
||||
<constraint firstItem="hJj-TC-pxK" firstAttribute="top" secondItem="fdx-qs-8en" secondAttribute="top" id="ovD-8p-4dP"/>
|
||||
<constraint firstAttribute="width" constant="100" id="ryE-fW-SgG"/>
|
||||
<constraint firstAttribute="trailing" secondItem="eU5-iK-u8i" secondAttribute="trailing" id="teG-8q-BOX"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="GGt-zb-6zg">
|
||||
<rect key="frame" x="48" y="0.0" width="486" height="26"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="hgp-Z5-rAj" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="5" id="2Ih-ga-N9s"/>
|
||||
<constraint firstItem="kwd-hP-feC" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" id="5bB-HV-WAA"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="leading" secondItem="hgp-Z5-rAj" secondAttribute="trailing" constant="3" id="6mM-Ag-m0K"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="18" id="96U-67-5TP"/>
|
||||
<constraint firstAttribute="trailing" secondItem="q9c-0p-QyP" secondAttribute="trailing" constant="69" id="Bkh-h2-JOQ"/>
|
||||
<constraint firstItem="GGt-zb-6zg" firstAttribute="leading" secondItem="q9c-0p-QyP" secondAttribute="leading" constant="-3" id="CsE-Bf-Wq7"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="centerY" secondItem="Cot-3X-2cU" secondAttribute="centerY" id="H5t-l6-fL1"/>
|
||||
<constraint firstItem="q9c-0p-QyP" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="3" id="Ixr-7h-f8j"/>
|
||||
<constraint firstItem="GGt-zb-6zg" firstAttribute="trailing" secondItem="q9c-0p-QyP" secondAttribute="trailing" constant="3" id="Ku9-ad-hb4"/>
|
||||
<constraint firstAttribute="bottom" secondItem="kwd-hP-feC" secondAttribute="bottom" id="LQg-cI-Nkn"/>
|
||||
<constraint firstAttribute="bottom" secondItem="5IE-JS-uf3" secondAttribute="bottom" constant="8" id="SHN-tC-zsJ"/>
|
||||
<constraint firstAttribute="bottom" secondItem="IOg-Kt-8vW" secondAttribute="bottom" id="TPw-iE-nii"/>
|
||||
<constraint firstItem="IOg-Kt-8vW" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="18" id="XSL-TG-m62"/>
|
||||
<constraint firstItem="q9c-0p-QyP" firstAttribute="leading" secondItem="hgp-Z5-rAj" secondAttribute="trailing" constant="3" id="YWK-C2-15w"/>
|
||||
<constraint firstItem="GGt-zb-6zg" firstAttribute="top" secondItem="q9c-0p-QyP" secondAttribute="top" constant="-3" id="cqf-j2-9vP"/>
|
||||
<constraint firstItem="zwq-eh-8Fb" firstAttribute="leading" secondItem="ef1-Tq-U3Z" secondAttribute="leading" constant="5" id="dgK-4e-UuE"/>
|
||||
<constraint firstAttribute="trailing" secondItem="kwd-hP-feC" secondAttribute="trailing" id="f2V-Ka-kU3"/>
|
||||
<constraint firstAttribute="trailing" secondItem="IOg-Kt-8vW" secondAttribute="trailing" constant="8" id="hQV-lO-7aQ"/>
|
||||
<constraint firstItem="GGt-zb-6zg" firstAttribute="bottom" secondItem="q9c-0p-QyP" secondAttribute="bottom" constant="3" id="kYd-0y-Rcu"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="leading" secondItem="K9X-gn-noF" secondAttribute="leading" id="p93-5h-lvW"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="centerX" secondItem="Cot-3X-2cU" secondAttribute="centerX" id="sF7-QL-vdj"/>
|
||||
<constraint firstItem="zwq-eh-8Fb" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" id="tUd-UR-lzA"/>
|
||||
<constraint firstItem="hgp-Z5-rAj" firstAttribute="leading" secondItem="ef1-Tq-U3Z" secondAttribute="leading" constant="8" id="tuw-aU-ncu"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="centerY" secondItem="fdx-qs-8en" secondAttribute="centerY" id="v0F-Ts-14P"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="top" secondItem="K9X-gn-noF" secondAttribute="top" id="wkX-zQ-iQS"/>
|
||||
<constraint firstAttribute="trailing" secondItem="fdx-qs-8en" secondAttribute="trailing" constant="13" id="xKk-Gz-moE"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="attachViewBottomConstraint" destination="SHN-tC-zsJ" id="cG0-a7-eHa"/>
|
||||
<outlet property="attachViewMinHeightConstraint" destination="C5F-6D-LZx" id="frk-Ox-WbA"/>
|
||||
<outlet property="attachViewTopConstraint" destination="96U-67-5TP" id="Ugm-cH-32E"/>
|
||||
<outlet property="attachViewWidthConstraint" destination="9zO-jU-qTb" id="fOO-VW-fe1"/>
|
||||
<outlet property="attachmentView" destination="5IE-JS-uf3" id="imT-1z-hR1"/>
|
||||
<outlet property="bubbleInfoContainer" destination="IOg-Kt-8vW" id="TAw-QY-Y9e"/>
|
||||
<outlet property="bubbleInfoContainerTopConstraint" destination="XSL-TG-m62" id="qVf-vJ-4aP"/>
|
||||
<outlet property="fileTypeIconView" destination="K9X-gn-noF" id="4Pj-bc-3gk"/>
|
||||
<outlet property="pictureView" destination="hgp-Z5-rAj" id="rKM-QG-RJN"/>
|
||||
<outlet property="playIconView" destination="Cot-3X-2cU" id="KEF-KK-Og1"/>
|
||||
<outlet property="progressChartView" destination="hJj-TC-pxK" id="Zz3-s5-Qqr"/>
|
||||
<outlet property="progressView" destination="fdx-qs-8en" id="V7E-pn-Xze"/>
|
||||
<outlet property="statsLabel" destination="eU5-iK-u8i" id="MSm-kU-RSY"/>
|
||||
<outlet property="typingBadge" destination="zwq-eh-8Fb" id="4vs-Dk-vWt"/>
|
||||
<outlet property="userNameLabel" destination="q9c-0p-QyP" id="JId-R7-LoM"/>
|
||||
<outlet property="userNameTapGestureMaskView" destination="GGt-zb-6zg" id="uV1-Jm-vLT"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomIncomingAttachmentBubbleCell.h"
|
||||
|
||||
/**
|
||||
`MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell` displays incoming message bubbles without sender's information.
|
||||
*/
|
||||
@interface MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell : MXKRoomIncomingAttachmentBubbleCell
|
||||
|
||||
@end
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell.h"
|
||||
|
||||
@implementation MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell
|
||||
|
||||
@end
|
||||
-127
@@ -1,127 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="WmY-Jw-mqv" customClass="MXKRoomIncomingAttachmentWithoutSenderInfoBubbleCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WmY-Jw-mqv" id="ef1-Tq-U3Z">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="49"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="5IE-JS-uf3" userLabel="Attachment View" customClass="MXKImageView">
|
||||
<rect key="frame" x="51" y="8" width="192" height="33"/>
|
||||
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="192" id="9zO-jU-qTb"/>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="33" id="Uqr-7d-0dv"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="K9X-gn-noF" userLabel="File Type Image View">
|
||||
<rect key="frame" x="51" y="8" width="32" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="32" id="OE8-oh-B7Q"/>
|
||||
<constraint firstAttribute="height" constant="32" id="jJB-zj-fbT"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="Cot-3X-2cU" userLabel="Play Icon Image View">
|
||||
<rect key="frame" x="131" y="9" width="32" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="32" id="8io-Wk-GzF"/>
|
||||
<constraint firstAttribute="width" constant="32" id="aeJ-j3-rfX"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kwd-hP-feC" userLabel="showHideDateTime">
|
||||
<rect key="frame" x="531" y="0.0" width="69" height="49"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="69" id="9vA-4g-EE5"/>
|
||||
</constraints>
|
||||
<state key="normal">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="showHideDateTime:" destination="WmY-Jw-mqv" eventType="touchUpInside" id="jYV-nj-p60"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IOg-Kt-8vW" userLabel="bubbleInfoContainer">
|
||||
<rect key="frame" x="531" y="8" width="61" height="41"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="61" id="tLr-6k-ArA"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="fdx-qs-8en" userLabel="ProgressView">
|
||||
<rect key="frame" x="487" y="-10" width="100" height="70"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="rate" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" minimumFontSize="4" preferredMaxLayoutWidth="100" translatesAutoresizingMaskIntoConstraints="NO" id="eU5-iK-u8i" userLabel="Progress stats">
|
||||
<rect key="frame" x="0.0" y="60" width="100" height="10"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="8"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="hJj-TC-pxK" customClass="MXKPieChartView">
|
||||
<rect key="frame" x="30" y="0.0" width="40" height="40"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="40" id="Cpt-s4-tlK"/>
|
||||
<constraint firstAttribute="height" constant="40" id="Jb4-9E-tG0"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<gestureRecognizers/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="70" id="5w2-Hm-hZx"/>
|
||||
<constraint firstAttribute="centerX" secondItem="eU5-iK-u8i" secondAttribute="centerX" id="APi-aE-mLc"/>
|
||||
<constraint firstItem="eU5-iK-u8i" firstAttribute="leading" secondItem="fdx-qs-8en" secondAttribute="leading" id="Njw-3a-E9Y"/>
|
||||
<constraint firstAttribute="bottom" secondItem="eU5-iK-u8i" secondAttribute="bottom" id="QMO-g9-QVE"/>
|
||||
<constraint firstAttribute="centerX" secondItem="hJj-TC-pxK" secondAttribute="centerX" id="laR-Vg-ol3"/>
|
||||
<constraint firstItem="hJj-TC-pxK" firstAttribute="top" secondItem="fdx-qs-8en" secondAttribute="top" id="ovD-8p-4dP"/>
|
||||
<constraint firstAttribute="width" constant="100" id="ryE-fW-SgG"/>
|
||||
<constraint firstAttribute="trailing" secondItem="eU5-iK-u8i" secondAttribute="trailing" id="teG-8q-BOX"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kwd-hP-feC" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" id="5bB-HV-WAA"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="8" id="96U-67-5TP"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="centerY" secondItem="Cot-3X-2cU" secondAttribute="centerY" id="H5t-l6-fL1"/>
|
||||
<constraint firstAttribute="bottom" secondItem="kwd-hP-feC" secondAttribute="bottom" id="LQg-cI-Nkn"/>
|
||||
<constraint firstAttribute="bottom" secondItem="5IE-JS-uf3" secondAttribute="bottom" constant="8" id="SHN-tC-zsJ"/>
|
||||
<constraint firstAttribute="bottom" secondItem="IOg-Kt-8vW" secondAttribute="bottom" id="TPw-iE-nii"/>
|
||||
<constraint firstItem="IOg-Kt-8vW" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="8" id="XSL-TG-m62"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="leading" secondItem="ef1-Tq-U3Z" secondAttribute="leading" constant="51" id="bSL-lG-ued"/>
|
||||
<constraint firstAttribute="trailing" secondItem="kwd-hP-feC" secondAttribute="trailing" id="f2V-Ka-kU3"/>
|
||||
<constraint firstAttribute="trailing" secondItem="IOg-Kt-8vW" secondAttribute="trailing" constant="8" id="hQV-lO-7aQ"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="leading" secondItem="K9X-gn-noF" secondAttribute="leading" id="p93-5h-lvW"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="centerX" secondItem="Cot-3X-2cU" secondAttribute="centerX" id="sF7-QL-vdj"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="centerY" secondItem="fdx-qs-8en" secondAttribute="centerY" id="v0F-Ts-14P"/>
|
||||
<constraint firstItem="5IE-JS-uf3" firstAttribute="top" secondItem="K9X-gn-noF" secondAttribute="top" id="wkX-zQ-iQS"/>
|
||||
<constraint firstAttribute="trailing" secondItem="fdx-qs-8en" secondAttribute="trailing" constant="13" id="xKk-Gz-moE"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="attachViewBottomConstraint" destination="SHN-tC-zsJ" id="cG0-a7-eHa"/>
|
||||
<outlet property="attachViewMinHeightConstraint" destination="Uqr-7d-0dv" id="UIs-4K-np5"/>
|
||||
<outlet property="attachViewTopConstraint" destination="96U-67-5TP" id="Ugm-cH-32E"/>
|
||||
<outlet property="attachViewWidthConstraint" destination="9zO-jU-qTb" id="fOO-VW-fe1"/>
|
||||
<outlet property="attachmentView" destination="5IE-JS-uf3" id="imT-1z-hR1"/>
|
||||
<outlet property="bubbleInfoContainer" destination="IOg-Kt-8vW" id="TAw-QY-Y9e"/>
|
||||
<outlet property="bubbleInfoContainerTopConstraint" destination="XSL-TG-m62" id="qVf-vJ-4aP"/>
|
||||
<outlet property="fileTypeIconView" destination="K9X-gn-noF" id="4Pj-bc-3gk"/>
|
||||
<outlet property="playIconView" destination="Cot-3X-2cU" id="KEF-KK-Og1"/>
|
||||
<outlet property="progressChartView" destination="hJj-TC-pxK" id="Zz3-s5-Qqr"/>
|
||||
<outlet property="progressView" destination="fdx-qs-8en" id="V7E-pn-Xze"/>
|
||||
<outlet property="statsLabel" destination="eU5-iK-u8i" id="MSm-kU-RSY"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,29 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomBubbleTableViewCell.h"
|
||||
|
||||
/**
|
||||
`MXKRoomIncomingBubbleTableViewCell` inherits from 'MXKRoomBubbleTableViewCell' class in order to handle specific
|
||||
options related to incoming messages (like typing badge).
|
||||
|
||||
In order to optimize bubbles rendering, we advise to define a .xib for each layout.
|
||||
*/
|
||||
@interface MXKRoomIncomingBubbleTableViewCell : MXKRoomBubbleTableViewCell
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *typingBadge;
|
||||
|
||||
@end
|
||||
@@ -1,65 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomIncomingBubbleTableViewCell.h"
|
||||
|
||||
#import "MXKRoomBubbleCellData.h"
|
||||
|
||||
#import "NSBundle+MatrixKit.h"
|
||||
|
||||
@implementation MXKRoomIncomingBubbleTableViewCell
|
||||
|
||||
- (void)finalizeInit
|
||||
{
|
||||
[super finalizeInit];
|
||||
self.readReceiptsAlignment = ReadReceiptAlignmentRight;
|
||||
}
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
[super awakeFromNib];
|
||||
self.typingBadge.image = [NSBundle mxk_imageFromMXKAssetsBundleWithName:@"icon_keyboard"];
|
||||
}
|
||||
|
||||
- (void)render:(MXKCellData *)cellData
|
||||
{
|
||||
[super render:cellData];
|
||||
|
||||
if (bubbleData)
|
||||
{
|
||||
// Handle here typing badge (if any)
|
||||
if (self.typingBadge)
|
||||
{
|
||||
if (bubbleData.isTyping)
|
||||
{
|
||||
self.typingBadge.hidden = NO;
|
||||
[self.typingBadge.superview bringSubviewToFront:self.typingBadge];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.typingBadge.hidden = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didEndDisplay
|
||||
{
|
||||
[super didEndDisplay];
|
||||
self.readReceiptsAlignment = ReadReceiptAlignmentRight;
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomIncomingBubbleTableViewCell.h"
|
||||
|
||||
/**
|
||||
`MXKRoomIncomingTextMsgBubbleCell` displays incoming message bubbles with sender's information.
|
||||
*/
|
||||
@interface MXKRoomIncomingTextMsgBubbleCell : MXKRoomIncomingBubbleTableViewCell
|
||||
|
||||
@end
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomIncomingTextMsgBubbleCell.h"
|
||||
|
||||
@implementation MXKRoomIncomingTextMsgBubbleCell
|
||||
|
||||
@end
|
||||
@@ -1,124 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="WmY-Jw-mqv" customClass="MXKRoomIncomingTextMsgBubbleCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WmY-Jw-mqv" id="ef1-Tq-U3Z">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="49.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleAspectFill" translatesAutoresizingMaskIntoConstraints="NO" id="hgp-Z5-rAj" userLabel="Picture View" customClass="MXKImageView">
|
||||
<rect key="frame" x="8" y="5" width="40" height="40"/>
|
||||
<color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="40" id="NQk-ck-Lo8"/>
|
||||
<constraint firstAttribute="height" constant="40" id="dNT-QU-CUG"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="zwq-eh-8Fb" userLabel="typingBadge">
|
||||
<rect key="frame" x="5" y="0.0" width="20" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="20" id="7ni-rb-ovL"/>
|
||||
<constraint firstAttribute="height" constant="20" id="mcu-rQ-hnj"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="User name:" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumFontSize="8" translatesAutoresizingMaskIntoConstraints="NO" id="q9c-0p-QyP">
|
||||
<rect key="frame" x="51" y="3" width="480" height="20"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="20" placeholder="YES" id="5ZO-W1-tS2"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<color key="textColor" red="0.33333333333333331" green="0.33333333333333331" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" text="text message" translatesAutoresizingMaskIntoConstraints="NO" id="HTH-5n-MSU" customClass="MXKMessageTextView">
|
||||
<rect key="frame" x="51" y="10" width="97" height="39.5"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="97" id="9EQ-AP-La0"/>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="39" id="ZZt-rc-tVJ"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
<dataDetectorType key="dataDetectorTypes" link="YES"/>
|
||||
</textView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kwd-hP-feC" userLabel="showHideDateTime">
|
||||
<rect key="frame" x="531" y="0.0" width="69" height="49.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="69" id="9vA-4g-EE5"/>
|
||||
</constraints>
|
||||
<state key="normal">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="showHideDateTime:" destination="WmY-Jw-mqv" eventType="touchUpInside" id="jYV-nj-p60"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IOg-Kt-8vW" userLabel="bubbleInfoContainer">
|
||||
<rect key="frame" x="531" y="10" width="61" height="39.5"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="61" id="tLr-6k-ArA"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="L3N-gy-H1n">
|
||||
<rect key="frame" x="48" y="0.0" width="486" height="26"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="hgp-Z5-rAj" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="5" id="2Ih-ga-N9s"/>
|
||||
<constraint firstItem="kwd-hP-feC" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" id="5bB-HV-WAA"/>
|
||||
<constraint firstItem="L3N-gy-H1n" firstAttribute="leading" secondItem="q9c-0p-QyP" secondAttribute="leading" constant="-3" id="7gc-A2-DNj"/>
|
||||
<constraint firstAttribute="trailing" secondItem="q9c-0p-QyP" secondAttribute="trailing" constant="69" id="Bkh-h2-JOQ"/>
|
||||
<constraint firstItem="L3N-gy-H1n" firstAttribute="trailing" secondItem="q9c-0p-QyP" secondAttribute="trailing" constant="3" id="FLX-Dd-CqO"/>
|
||||
<constraint firstItem="L3N-gy-H1n" firstAttribute="bottom" secondItem="q9c-0p-QyP" secondAttribute="bottom" constant="3" id="IpR-cp-Yod"/>
|
||||
<constraint firstItem="q9c-0p-QyP" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="3" id="Ixr-7h-f8j"/>
|
||||
<constraint firstAttribute="bottom" secondItem="kwd-hP-feC" secondAttribute="bottom" id="LQg-cI-Nkn"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="HTH-5n-MSU" secondAttribute="trailing" constant="69" id="Shz-6S-kGd"/>
|
||||
<constraint firstAttribute="bottom" secondItem="IOg-Kt-8vW" secondAttribute="bottom" id="TPw-iE-nii"/>
|
||||
<constraint firstItem="IOg-Kt-8vW" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="10" id="XSL-TG-m62"/>
|
||||
<constraint firstItem="q9c-0p-QyP" firstAttribute="leading" secondItem="hgp-Z5-rAj" secondAttribute="trailing" constant="3" id="YWK-C2-15w"/>
|
||||
<constraint firstItem="zwq-eh-8Fb" firstAttribute="leading" secondItem="ef1-Tq-U3Z" secondAttribute="leading" constant="5" id="dgK-4e-UuE"/>
|
||||
<constraint firstAttribute="trailing" secondItem="kwd-hP-feC" secondAttribute="trailing" id="f2V-Ka-kU3"/>
|
||||
<constraint firstAttribute="trailing" secondItem="IOg-Kt-8vW" secondAttribute="trailing" constant="8" id="hQV-lO-7aQ"/>
|
||||
<constraint firstItem="HTH-5n-MSU" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" constant="10" id="mkw-3s-H8B"/>
|
||||
<constraint firstAttribute="bottom" secondItem="HTH-5n-MSU" secondAttribute="bottom" id="oTk-3F-SEC"/>
|
||||
<constraint firstItem="zwq-eh-8Fb" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" id="tUd-UR-lzA"/>
|
||||
<constraint firstItem="L3N-gy-H1n" firstAttribute="top" secondItem="q9c-0p-QyP" secondAttribute="top" constant="-3" id="tXi-p0-wft"/>
|
||||
<constraint firstItem="hgp-Z5-rAj" firstAttribute="leading" secondItem="ef1-Tq-U3Z" secondAttribute="leading" constant="8" id="tuw-aU-ncu"/>
|
||||
<constraint firstItem="HTH-5n-MSU" firstAttribute="leading" secondItem="ef1-Tq-U3Z" secondAttribute="leading" constant="51" id="uig-Xh-7m6"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="bubbleInfoContainer" destination="IOg-Kt-8vW" id="TAw-QY-Y9e"/>
|
||||
<outlet property="bubbleInfoContainerTopConstraint" destination="XSL-TG-m62" id="qVf-vJ-4aP"/>
|
||||
<outlet property="messageTextView" destination="HTH-5n-MSU" id="YN4-iK-gNc"/>
|
||||
<outlet property="msgTextViewBottomConstraint" destination="oTk-3F-SEC" id="o0p-3S-hM4"/>
|
||||
<outlet property="msgTextViewLeadingConstraint" destination="uig-Xh-7m6" id="kgj-3v-ECW"/>
|
||||
<outlet property="msgTextViewMinHeightConstraint" destination="ZZt-rc-tVJ" id="hDD-TL-PFM"/>
|
||||
<outlet property="msgTextViewTopConstraint" destination="mkw-3s-H8B" id="lON-oG-Xx9"/>
|
||||
<outlet property="msgTextViewTrailingConstraint" destination="Shz-6S-kGd" id="5ib-m6-Lna"/>
|
||||
<outlet property="msgTextViewWidthConstraint" destination="9EQ-AP-La0" id="wgi-Yc-sTT"/>
|
||||
<outlet property="pictureView" destination="hgp-Z5-rAj" id="rKM-QG-RJN"/>
|
||||
<outlet property="typingBadge" destination="zwq-eh-8Fb" id="4vs-Dk-vWt"/>
|
||||
<outlet property="userNameLabel" destination="q9c-0p-QyP" id="JId-R7-LoM"/>
|
||||
<outlet property="userNameTapGestureMaskView" destination="L3N-gy-H1n" id="1Eb-Vn-fSP"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomIncomingTextMsgBubbleCell.h"
|
||||
|
||||
/**
|
||||
`MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell` displays incoming message bubbles without sender's information.
|
||||
*/
|
||||
@interface MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell : MXKRoomIncomingTextMsgBubbleCell
|
||||
|
||||
@end
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell.h"
|
||||
|
||||
@implementation MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell
|
||||
|
||||
@end
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="WmY-Jw-mqv" customClass="MXKRoomIncomingTextMsgWithoutSenderInfoBubbleCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="35"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="WmY-Jw-mqv" id="ef1-Tq-U3Z">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="34.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" text="text message" translatesAutoresizingMaskIntoConstraints="NO" id="HTH-5n-MSU" customClass="MXKMessageTextView">
|
||||
<rect key="frame" x="51" y="0.0" width="97" height="34.5"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="29" id="SHB-dF-A5J"/>
|
||||
<constraint firstAttribute="width" constant="97" id="aQ3-Pg-LVD"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
<dataDetectorType key="dataDetectorTypes" link="YES"/>
|
||||
</textView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kwd-hP-feC" userLabel="showHideDateTime">
|
||||
<rect key="frame" x="531" y="0.0" width="69" height="34.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="69" id="9vA-4g-EE5"/>
|
||||
</constraints>
|
||||
<state key="normal">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="showHideDateTime:" destination="WmY-Jw-mqv" eventType="touchUpInside" id="jYV-nj-p60"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="IOg-Kt-8vW" userLabel="bubbleInfoContainer">
|
||||
<rect key="frame" x="531" y="0.0" width="61" height="34.5"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="61" id="tLr-6k-ArA"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="kwd-hP-feC" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" id="5bB-HV-WAA"/>
|
||||
<constraint firstAttribute="bottom" secondItem="kwd-hP-feC" secondAttribute="bottom" id="LQg-cI-Nkn"/>
|
||||
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="HTH-5n-MSU" secondAttribute="trailing" constant="69" id="Shz-6S-kGd"/>
|
||||
<constraint firstAttribute="bottom" secondItem="IOg-Kt-8vW" secondAttribute="bottom" id="TPw-iE-nii"/>
|
||||
<constraint firstItem="IOg-Kt-8vW" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" id="XSL-TG-m62"/>
|
||||
<constraint firstAttribute="trailing" secondItem="kwd-hP-feC" secondAttribute="trailing" id="f2V-Ka-kU3"/>
|
||||
<constraint firstAttribute="trailing" secondItem="IOg-Kt-8vW" secondAttribute="trailing" constant="8" id="hQV-lO-7aQ"/>
|
||||
<constraint firstItem="HTH-5n-MSU" firstAttribute="top" secondItem="ef1-Tq-U3Z" secondAttribute="top" id="mkw-3s-H8B"/>
|
||||
<constraint firstAttribute="bottom" secondItem="HTH-5n-MSU" secondAttribute="bottom" id="oTk-3F-SEC"/>
|
||||
<constraint firstItem="HTH-5n-MSU" firstAttribute="leading" secondItem="ef1-Tq-U3Z" secondAttribute="leading" constant="51" id="uig-Xh-7m6"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="bubbleInfoContainer" destination="IOg-Kt-8vW" id="TAw-QY-Y9e"/>
|
||||
<outlet property="bubbleInfoContainerTopConstraint" destination="XSL-TG-m62" id="qVf-vJ-4aP"/>
|
||||
<outlet property="messageTextView" destination="HTH-5n-MSU" id="YN4-iK-gNc"/>
|
||||
<outlet property="msgTextViewBottomConstraint" destination="oTk-3F-SEC" id="86P-vn-8mz"/>
|
||||
<outlet property="msgTextViewLeadingConstraint" destination="uig-Xh-7m6" id="kgj-3v-ECW"/>
|
||||
<outlet property="msgTextViewMinHeightConstraint" destination="SHB-dF-A5J" id="RjV-W7-QaK"/>
|
||||
<outlet property="msgTextViewTopConstraint" destination="mkw-3s-H8B" id="lON-oG-Xx9"/>
|
||||
<outlet property="msgTextViewTrailingConstraint" destination="Shz-6S-kGd" id="5ib-m6-Lna"/>
|
||||
<outlet property="msgTextViewWidthConstraint" destination="aQ3-Pg-LVD" id="JPV-up-dzy"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,26 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomOutgoingBubbleTableViewCell.h"
|
||||
|
||||
/**
|
||||
`MXKRoomOutgoingAttachmentBubbleCell` displays outgoing attachment bubbles.
|
||||
*/
|
||||
@interface MXKRoomOutgoingAttachmentBubbleCell : MXKRoomOutgoingBubbleTableViewCell
|
||||
|
||||
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *activityIndicator;
|
||||
|
||||
@end
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
Copyright 2018 New Vector Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomOutgoingAttachmentBubbleCell.h"
|
||||
|
||||
#import "MXEvent+MatrixKit.h"
|
||||
|
||||
#import "MXKRoomBubbleCellData.h"
|
||||
#import "MXKImageView.h"
|
||||
#import "MXKPieChartView.h"
|
||||
|
||||
@implementation MXKRoomOutgoingAttachmentBubbleCell
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
[self stopAnimating];
|
||||
}
|
||||
|
||||
- (void)render:(MXKCellData *)cellData
|
||||
{
|
||||
[super render:cellData];
|
||||
|
||||
if (bubbleData)
|
||||
{
|
||||
// Do not display activity indicator on outgoing attachments (These attachments are supposed to be stored locally)
|
||||
// Some download may append to retrieve the actual thumbnail after posting an image.
|
||||
self.attachmentView.hideActivityIndicator = YES;
|
||||
|
||||
// Check if the attachment is uploading
|
||||
MXKRoomBubbleComponent *component = bubbleData.bubbleComponents.firstObject;
|
||||
if (component.event.sentState == MXEventSentStatePreparing || component.event.sentState == MXEventSentStateEncrypting || component.event.sentState == MXEventSentStateUploading)
|
||||
{
|
||||
// Retrieve the uploadId embedded in the fake url
|
||||
bubbleData.uploadId = component.event.content[@"url"];
|
||||
|
||||
self.attachmentView.alpha = 0.5;
|
||||
|
||||
// Start showing upload progress
|
||||
[self startUploadAnimating];
|
||||
}
|
||||
else if (component.event.sentState == MXEventSentStateSending)
|
||||
{
|
||||
self.attachmentView.alpha = 0.5;
|
||||
[self.activityIndicator startAnimating];
|
||||
}
|
||||
else if (component.event.sentState == MXEventSentStateFailed)
|
||||
{
|
||||
self.attachmentView.alpha = 0.5;
|
||||
[self.activityIndicator stopAnimating];
|
||||
}
|
||||
else
|
||||
{
|
||||
self.attachmentView.alpha = 1;
|
||||
[self.activityIndicator stopAnimating];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didEndDisplay
|
||||
{
|
||||
[super didEndDisplay];
|
||||
|
||||
// Hide potential loading wheel
|
||||
[self stopAnimating];
|
||||
}
|
||||
|
||||
-(void)startUploadAnimating
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXMediaLoaderStateDidChangeNotification object:nil];
|
||||
|
||||
[self.activityIndicator startAnimating];
|
||||
|
||||
MXMediaLoader *uploader = [MXMediaManager existingUploaderWithId:bubbleData.uploadId];
|
||||
if (uploader)
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(onMediaLoaderStateDidChange:) name:kMXMediaLoaderStateDidChangeNotification object:uploader];
|
||||
|
||||
if (uploader.statisticsDict)
|
||||
{
|
||||
[self.activityIndicator stopAnimating];
|
||||
[self updateProgressUI:uploader.statisticsDict];
|
||||
|
||||
// Check whether the upload is ended
|
||||
if (self.progressChartView.progress == 1.0)
|
||||
{
|
||||
[self stopAnimating];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
self.progressView.hidden = YES;
|
||||
}
|
||||
}
|
||||
|
||||
-(void)stopAnimating
|
||||
{
|
||||
self.progressView.hidden = YES;
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:kMXMediaLoaderStateDidChangeNotification object:nil];
|
||||
[self.activityIndicator stopAnimating];
|
||||
}
|
||||
|
||||
- (void)onMediaLoaderStateDidChange:(NSNotification *)notif
|
||||
{
|
||||
MXMediaLoader *loader = (MXMediaLoader*)notif.object;
|
||||
|
||||
// Consider only the progress of the current upload.
|
||||
if ([loader.uploadId isEqualToString:bubbleData.uploadId])
|
||||
{
|
||||
switch (loader.state) {
|
||||
case MXMediaLoaderStateUploadInProgress:
|
||||
{
|
||||
[self.activityIndicator stopAnimating];
|
||||
[self updateProgressUI:loader.statisticsDict];
|
||||
|
||||
// the upload is ended
|
||||
if (self.progressChartView.progress == 1.0)
|
||||
{
|
||||
[self stopAnimating];
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,144 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="pad-g3-2YJ" customClass="MXKRoomOutgoingAttachmentBubbleCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="pad-g3-2YJ" id="fCg-ju-gnG">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="49"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleAspectFill" translatesAutoresizingMaskIntoConstraints="NO" id="ezT-Dl-ESR" userLabel="Picture View" customClass="MXKImageView">
|
||||
<rect key="frame" x="552" y="5" width="40" height="40"/>
|
||||
<color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="40" id="JHc-dD-geb"/>
|
||||
<constraint firstAttribute="height" constant="40" id="lFb-Jo-C7R"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="SIW-l4-PfI" userLabel="Attachment View" customClass="MXKImageView">
|
||||
<rect key="frame" x="357" y="18" width="192" height="23"/>
|
||||
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="192" id="iGr-e7-bde"/>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="23" id="kGW-IH-XnB"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="KGx-6M-GER" userLabel="File Type Image View">
|
||||
<rect key="frame" x="357" y="18" width="32" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="32" id="QGB-Md-MLn"/>
|
||||
<constraint firstAttribute="width" constant="32" id="h7Q-f3-gtz"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ZC1-hT-7fs" userLabel="Play Icon Image View">
|
||||
<rect key="frame" x="437" y="14" width="32" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="32" id="MOQ-Xi-18w"/>
|
||||
<constraint firstAttribute="height" constant="32" id="pGM-pf-SiP"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="Mqf-7a-bsm">
|
||||
<rect key="frame" x="443" y="20" width="20" height="20"/>
|
||||
</activityIndicatorView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LVJ-Av-zVs" userLabel="showHideDateTime">
|
||||
<rect key="frame" x="0.0" y="0.0" width="69" height="49"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="69" id="ghQ-Qb-BBg"/>
|
||||
</constraints>
|
||||
<state key="normal">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="showHideDateTime:" destination="pad-g3-2YJ" eventType="touchUpInside" id="Ztw-z5-zlU"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a51-cR-7FE" userLabel="bubbleInfoContainer">
|
||||
<rect key="frame" x="8" y="18" width="61" height="31"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="61" id="fDy-iL-hrD"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="apW-hM-veR" userLabel="ProgressView">
|
||||
<rect key="frame" x="18" y="-5" width="100" height="70"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="text" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" minimumFontSize="4" preferredMaxLayoutWidth="100" translatesAutoresizingMaskIntoConstraints="NO" id="DYj-Mb-me4" userLabel="Progress stats">
|
||||
<rect key="frame" x="0.0" y="60" width="100" height="10"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="8"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Oec-kb-Tsz" customClass="MXKPieChartView">
|
||||
<rect key="frame" x="30" y="0.0" width="40" height="40"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="40" id="6tZ-ag-7TT"/>
|
||||
<constraint firstAttribute="width" constant="40" id="duC-38-cLC"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<gestureRecognizers/>
|
||||
<constraints>
|
||||
<constraint firstItem="Oec-kb-Tsz" firstAttribute="top" secondItem="apW-hM-veR" secondAttribute="top" id="49H-ch-qkC"/>
|
||||
<constraint firstAttribute="height" constant="70" id="GhG-zB-k3A"/>
|
||||
<constraint firstAttribute="centerX" secondItem="Oec-kb-Tsz" secondAttribute="centerX" id="KZy-2p-KaW"/>
|
||||
<constraint firstItem="DYj-Mb-me4" firstAttribute="leading" secondItem="apW-hM-veR" secondAttribute="leading" id="UxL-bV-5Ca"/>
|
||||
<constraint firstAttribute="bottom" secondItem="DYj-Mb-me4" secondAttribute="bottom" id="YFp-gQ-NFz"/>
|
||||
<constraint firstAttribute="width" constant="100" id="Zr4-5T-h9g"/>
|
||||
<constraint firstAttribute="trailing" secondItem="DYj-Mb-me4" secondAttribute="trailing" id="ehN-ME-1U1"/>
|
||||
<constraint firstAttribute="centerX" secondItem="DYj-Mb-me4" secondAttribute="centerX" id="nuq-lO-8pT"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="centerX" secondItem="Mqf-7a-bsm" secondAttribute="centerX" id="1b6-1l-hg0"/>
|
||||
<constraint firstAttribute="trailing" secondItem="ezT-Dl-ESR" secondAttribute="trailing" constant="8" id="3Pd-Qy-Xva"/>
|
||||
<constraint firstItem="ezT-Dl-ESR" firstAttribute="leading" secondItem="SIW-l4-PfI" secondAttribute="trailing" constant="3" id="9z3-D2-2SS"/>
|
||||
<constraint firstItem="a51-cR-7FE" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" constant="8" id="E3x-h8-GPF"/>
|
||||
<constraint firstItem="LVJ-Av-zVs" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" id="Hve-E3-z5N"/>
|
||||
<constraint firstAttribute="bottom" secondItem="LVJ-Av-zVs" secondAttribute="bottom" id="IKr-Dc-HKz"/>
|
||||
<constraint firstItem="apW-hM-veR" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" constant="18" id="LFn-vp-m0v"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" constant="18" id="QDm-tP-KWa"/>
|
||||
<constraint firstItem="ezT-Dl-ESR" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" constant="5" id="aHl-KA-68x"/>
|
||||
<constraint firstAttribute="bottom" secondItem="SIW-l4-PfI" secondAttribute="bottom" constant="8" id="fMN-Th-SOT"/>
|
||||
<constraint firstItem="a51-cR-7FE" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" constant="18" id="fQv-07-Pgx"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="centerY" secondItem="ZC1-hT-7fs" secondAttribute="centerY" id="ffI-vh-SW3"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="leading" secondItem="KGx-6M-GER" secondAttribute="leading" id="j1U-XX-IZW"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="centerX" secondItem="ZC1-hT-7fs" secondAttribute="centerX" id="jah-TA-P0P"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="top" secondItem="KGx-6M-GER" secondAttribute="top" id="loA-GI-HkT"/>
|
||||
<constraint firstItem="LVJ-Av-zVs" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" id="pYO-hi-P72"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="centerY" secondItem="Mqf-7a-bsm" secondAttribute="centerY" id="sKJ-ny-LjM"/>
|
||||
<constraint firstAttribute="bottom" secondItem="a51-cR-7FE" secondAttribute="bottom" id="viZ-Sx-3RW"/>
|
||||
<constraint firstItem="apW-hM-veR" firstAttribute="centerY" secondItem="SIW-l4-PfI" secondAttribute="centerY" id="wmh-x1-U32"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="activityIndicator" destination="Mqf-7a-bsm" id="toi-nL-eJa"/>
|
||||
<outlet property="attachViewBottomConstraint" destination="fMN-Th-SOT" id="WVk-1p-S0P"/>
|
||||
<outlet property="attachViewMinHeightConstraint" destination="kGW-IH-XnB" id="97f-NR-EDv"/>
|
||||
<outlet property="attachViewTopConstraint" destination="QDm-tP-KWa" id="Ku6-FC-jqo"/>
|
||||
<outlet property="attachViewWidthConstraint" destination="iGr-e7-bde" id="uD4-aU-1Ru"/>
|
||||
<outlet property="attachmentView" destination="SIW-l4-PfI" id="L4H-ub-pPI"/>
|
||||
<outlet property="bubbleInfoContainer" destination="a51-cR-7FE" id="wrR-cU-DVm"/>
|
||||
<outlet property="bubbleInfoContainerTopConstraint" destination="fQv-07-Pgx" id="82c-KH-Wop"/>
|
||||
<outlet property="fileTypeIconView" destination="KGx-6M-GER" id="MXF-4w-mY7"/>
|
||||
<outlet property="pictureView" destination="ezT-Dl-ESR" id="YsO-Kp-xaD"/>
|
||||
<outlet property="playIconView" destination="ZC1-hT-7fs" id="zeH-8B-gxw"/>
|
||||
<outlet property="progressChartView" destination="Oec-kb-Tsz" id="uoq-6v-6Tm"/>
|
||||
<outlet property="progressView" destination="apW-hM-veR" id="Iy8-ca-hMi"/>
|
||||
<outlet property="statsLabel" destination="DYj-Mb-me4" id="CbG-5V-unO"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomOutgoingAttachmentBubbleCell.h"
|
||||
|
||||
/**
|
||||
`MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell` displays outgoing attachment with thumbnail, without user's name.
|
||||
*/
|
||||
@interface MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell : MXKRoomOutgoingAttachmentBubbleCell
|
||||
|
||||
@end
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell.h"
|
||||
|
||||
@implementation MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell
|
||||
|
||||
@end
|
||||
-132
@@ -1,132 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16C67" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="11757"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="pad-g3-2YJ" customClass="MXKRoomOutgoingAttachmentWithoutSenderInfoBubbleCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="pad-g3-2YJ" id="fCg-ju-gnG">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="49"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleAspectFit" translatesAutoresizingMaskIntoConstraints="NO" id="SIW-l4-PfI" userLabel="Attachment View" customClass="MXKImageView">
|
||||
<rect key="frame" x="357" y="8" width="192" height="33"/>
|
||||
<color key="backgroundColor" red="0.93725490196078431" green="0.93725490196078431" blue="0.95686274509803926" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="192" id="iGr-e7-bde"/>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="33" id="nSK-Ug-3Q4"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="KGx-6M-GER" userLabel="File Type Image View">
|
||||
<rect key="frame" x="357" y="8" width="32" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="32" id="QGB-Md-MLn"/>
|
||||
<constraint firstAttribute="width" constant="32" id="h7Q-f3-gtz"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<imageView hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ZC1-hT-7fs" userLabel="Play Icon Image View">
|
||||
<rect key="frame" x="437" y="9" width="32" height="32"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="32" id="MOQ-Xi-18w"/>
|
||||
<constraint firstAttribute="height" constant="32" id="pGM-pf-SiP"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<activityIndicatorView hidden="YES" opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" style="gray" translatesAutoresizingMaskIntoConstraints="NO" id="Mqf-7a-bsm">
|
||||
<rect key="frame" x="443" y="15" width="20" height="20"/>
|
||||
</activityIndicatorView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LVJ-Av-zVs" userLabel="showHideDateTime">
|
||||
<rect key="frame" x="0.0" y="0.0" width="69" height="49"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="69" id="ghQ-Qb-BBg"/>
|
||||
</constraints>
|
||||
<state key="normal">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="showHideDateTime:" destination="pad-g3-2YJ" eventType="touchUpInside" id="Ztw-z5-zlU"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a51-cR-7FE" userLabel="bubbleInfoContainer">
|
||||
<rect key="frame" x="8" y="8" width="61" height="41"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="61" id="fDy-iL-hrD"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="apW-hM-veR" userLabel="ProgressView">
|
||||
<rect key="frame" x="18" y="-10" width="100" height="70"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="text" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" minimumFontSize="4" preferredMaxLayoutWidth="100" translatesAutoresizingMaskIntoConstraints="NO" id="DYj-Mb-me4" userLabel="Progress stats">
|
||||
<rect key="frame" x="0.0" y="60" width="100" height="10"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="8"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Oec-kb-Tsz" customClass="MXKPieChartView">
|
||||
<rect key="frame" x="30" y="0.0" width="40" height="40"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="40" id="6tZ-ag-7TT"/>
|
||||
<constraint firstAttribute="width" constant="40" id="duC-38-cLC"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<gestureRecognizers/>
|
||||
<constraints>
|
||||
<constraint firstItem="Oec-kb-Tsz" firstAttribute="top" secondItem="apW-hM-veR" secondAttribute="top" id="49H-ch-qkC"/>
|
||||
<constraint firstAttribute="height" constant="70" id="GhG-zB-k3A"/>
|
||||
<constraint firstAttribute="centerX" secondItem="Oec-kb-Tsz" secondAttribute="centerX" id="KZy-2p-KaW"/>
|
||||
<constraint firstItem="DYj-Mb-me4" firstAttribute="leading" secondItem="apW-hM-veR" secondAttribute="leading" id="UxL-bV-5Ca"/>
|
||||
<constraint firstAttribute="bottom" secondItem="DYj-Mb-me4" secondAttribute="bottom" id="YFp-gQ-NFz"/>
|
||||
<constraint firstAttribute="width" constant="100" id="Zr4-5T-h9g"/>
|
||||
<constraint firstAttribute="trailing" secondItem="DYj-Mb-me4" secondAttribute="trailing" id="ehN-ME-1U1"/>
|
||||
<constraint firstAttribute="centerX" secondItem="DYj-Mb-me4" secondAttribute="centerX" id="nuq-lO-8pT"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="centerX" secondItem="Mqf-7a-bsm" secondAttribute="centerX" id="1b6-1l-hg0"/>
|
||||
<constraint firstItem="a51-cR-7FE" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" constant="8" id="E3x-h8-GPF"/>
|
||||
<constraint firstItem="LVJ-Av-zVs" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" id="Hve-E3-z5N"/>
|
||||
<constraint firstAttribute="bottom" secondItem="LVJ-Av-zVs" secondAttribute="bottom" id="IKr-Dc-HKz"/>
|
||||
<constraint firstItem="apW-hM-veR" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" constant="18" id="LFn-vp-m0v"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" constant="8" id="QDm-tP-KWa"/>
|
||||
<constraint firstAttribute="bottom" secondItem="SIW-l4-PfI" secondAttribute="bottom" constant="8" id="fMN-Th-SOT"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="centerY" secondItem="ZC1-hT-7fs" secondAttribute="centerY" id="ffI-vh-SW3"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="leading" secondItem="KGx-6M-GER" secondAttribute="leading" id="j1U-XX-IZW"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="centerX" secondItem="ZC1-hT-7fs" secondAttribute="centerX" id="jah-TA-P0P"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="top" secondItem="KGx-6M-GER" secondAttribute="top" id="loA-GI-HkT"/>
|
||||
<constraint firstItem="LVJ-Av-zVs" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" id="pYO-hi-P72"/>
|
||||
<constraint firstItem="SIW-l4-PfI" firstAttribute="centerY" secondItem="Mqf-7a-bsm" secondAttribute="centerY" id="sKJ-ny-LjM"/>
|
||||
<constraint firstAttribute="bottom" secondItem="a51-cR-7FE" secondAttribute="bottom" id="viZ-Sx-3RW"/>
|
||||
<constraint firstAttribute="trailing" secondItem="SIW-l4-PfI" secondAttribute="trailing" constant="51" id="wgx-Zr-5R6"/>
|
||||
<constraint firstItem="apW-hM-veR" firstAttribute="centerY" secondItem="SIW-l4-PfI" secondAttribute="centerY" id="wmh-x1-U32"/>
|
||||
<constraint firstItem="a51-cR-7FE" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" constant="8" id="xop-v3-Xh2"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="activityIndicator" destination="Mqf-7a-bsm" id="toi-nL-eJa"/>
|
||||
<outlet property="attachViewBottomConstraint" destination="fMN-Th-SOT" id="fw0-N9-RUj"/>
|
||||
<outlet property="attachViewMinHeightConstraint" destination="nSK-Ug-3Q4" id="rfM-Ha-vVp"/>
|
||||
<outlet property="attachViewTopConstraint" destination="QDm-tP-KWa" id="Ku6-FC-jqo"/>
|
||||
<outlet property="attachViewWidthConstraint" destination="iGr-e7-bde" id="uD4-aU-1Ru"/>
|
||||
<outlet property="attachmentView" destination="SIW-l4-PfI" id="L4H-ub-pPI"/>
|
||||
<outlet property="bubbleInfoContainer" destination="a51-cR-7FE" id="wrR-cU-DVm"/>
|
||||
<outlet property="fileTypeIconView" destination="KGx-6M-GER" id="MXF-4w-mY7"/>
|
||||
<outlet property="playIconView" destination="ZC1-hT-7fs" id="zeH-8B-gxw"/>
|
||||
<outlet property="progressChartView" destination="Oec-kb-Tsz" id="uoq-6v-6Tm"/>
|
||||
<outlet property="progressView" destination="apW-hM-veR" id="Iy8-ca-hMi"/>
|
||||
<outlet property="statsLabel" destination="DYj-Mb-me4" id="CbG-5V-unO"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -1,27 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomBubbleTableViewCell.h"
|
||||
|
||||
/**
|
||||
`MXKRoomOutgoingBubbleTableViewCell` inherits from 'MXKRoomBubbleTableViewCell' class in order to handle specific
|
||||
options related to outgoing messages (like unsent labels, upload progress in case of attachment).
|
||||
|
||||
In order to optimize bubbles rendering, we advise to define a .xib for each layout.
|
||||
*/
|
||||
@interface MXKRoomOutgoingBubbleTableViewCell : MXKRoomBubbleTableViewCell
|
||||
|
||||
@end
|
||||
@@ -1,117 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomOutgoingBubbleTableViewCell.h"
|
||||
|
||||
#import "MXEvent+MatrixKit.h"
|
||||
|
||||
#import "NSBundle+Matrixkit.h"
|
||||
|
||||
#import "MXKRoomBubbleCellData.h"
|
||||
|
||||
#import "MXKSwiftHeader.h"
|
||||
|
||||
@implementation MXKRoomOutgoingBubbleTableViewCell
|
||||
|
||||
- (void)render:(MXKCellData *)cellData
|
||||
{
|
||||
[super render:cellData];
|
||||
|
||||
if (bubbleData)
|
||||
{
|
||||
// Add unsent label for failed components (except if the app customizes it)
|
||||
if (self.bubbleInfoContainer && (bubbleData.useCustomUnsentButton == NO))
|
||||
{
|
||||
for (MXKRoomBubbleComponent *component in bubbleData.bubbleComponents)
|
||||
{
|
||||
if (component.event.sentState == MXEventSentStateFailed)
|
||||
{
|
||||
UIButton *unsentButton = [[UIButton alloc] initWithFrame:CGRectMake(0, component.position.y, 58 , 20)];
|
||||
|
||||
[unsentButton setTitle:[MatrixKitL10n unsent] forState:UIControlStateNormal];
|
||||
[unsentButton setTitle:[MatrixKitL10n unsent] forState:UIControlStateSelected];
|
||||
[unsentButton setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
|
||||
[unsentButton setTitleColor:[UIColor redColor] forState:UIControlStateSelected];
|
||||
|
||||
unsentButton.backgroundColor = [UIColor whiteColor];
|
||||
unsentButton.titleLabel.font = [UIFont systemFontOfSize:14];
|
||||
|
||||
[unsentButton addTarget:self action:@selector(onResendToggle:) forControlEvents:UIControlEventTouchUpInside];
|
||||
|
||||
[self.bubbleInfoContainer addSubview:unsentButton];
|
||||
self.bubbleInfoContainer.hidden = NO;
|
||||
self.bubbleInfoContainer.userInteractionEnabled = YES;
|
||||
|
||||
// ensure that bubbleInfoContainer is at front to catch the tap event
|
||||
[self.bubbleInfoContainer.superview bringSubviewToFront:self.bubbleInfoContainer];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)didEndDisplay
|
||||
{
|
||||
[super didEndDisplay];
|
||||
|
||||
self.bubbleInfoContainer.userInteractionEnabled = NO;
|
||||
}
|
||||
|
||||
#pragma mark - User actions
|
||||
|
||||
- (IBAction)onResendToggle:(id)sender
|
||||
{
|
||||
if ([sender isKindOfClass:[UIButton class]] && self.delegate)
|
||||
{
|
||||
MXEvent *selectedEvent = nil;
|
||||
|
||||
NSArray *bubbleComponents = bubbleData.bubbleComponents;
|
||||
|
||||
if (bubbleComponents.count == 1)
|
||||
{
|
||||
MXKRoomBubbleComponent *component = [bubbleComponents firstObject];
|
||||
selectedEvent = component.event;
|
||||
}
|
||||
else if (bubbleComponents.count)
|
||||
{
|
||||
// Here the selected view is a textView (attachment has no more than one component)
|
||||
|
||||
// Look for the selected component
|
||||
UIButton *unsentButton = (UIButton *)sender;
|
||||
for (MXKRoomBubbleComponent *component in bubbleComponents)
|
||||
{
|
||||
// Ignore components without display.
|
||||
if (!component.attributedTextMessage)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (unsentButton.frame.origin.y == component.position.y)
|
||||
{
|
||||
selectedEvent = component.event;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (selectedEvent)
|
||||
{
|
||||
[self.delegate cell:self didRecognizeAction:kMXKRoomBubbleCellUnsentButtonPressed userInfo:@{kMXKRoomBubbleCellEventKey:selectedEvent}];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomOutgoingBubbleTableViewCell.h"
|
||||
|
||||
/**
|
||||
`MXKRoomOutgoingTextMsgBubbleCell` displays outgoing message bubbles with user's picture.
|
||||
*/
|
||||
@interface MXKRoomOutgoingTextMsgBubbleCell : MXKRoomOutgoingBubbleTableViewCell
|
||||
|
||||
@end
|
||||
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomOutgoingTextMsgBubbleCell.h"
|
||||
|
||||
@implementation MXKRoomOutgoingTextMsgBubbleCell
|
||||
|
||||
@end
|
||||
@@ -1,91 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="pad-g3-2YJ" customClass="MXKRoomOutgoingTextMsgBubbleCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="pad-g3-2YJ" id="fCg-ju-gnG">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="49.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleAspectFill" translatesAutoresizingMaskIntoConstraints="NO" id="ezT-Dl-ESR" userLabel="Picture View" customClass="MXKImageView">
|
||||
<rect key="frame" x="552" y="5" width="40" height="40"/>
|
||||
<color key="backgroundColor" red="0.66666666666666663" green="0.66666666666666663" blue="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="40" id="JHc-dD-geb"/>
|
||||
<constraint firstAttribute="height" constant="40" id="lFb-Jo-C7R"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" text="text message" translatesAutoresizingMaskIntoConstraints="NO" id="tgO-Rv-C7R" customClass="MXKMessageTextView">
|
||||
<rect key="frame" x="452" y="10" width="97" height="39.5"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="39" id="2xF-Uv-zZv"/>
|
||||
<constraint firstAttribute="width" constant="97" id="ghN-E7-j4d"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
<dataDetectorType key="dataDetectorTypes" link="YES"/>
|
||||
</textView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LVJ-Av-zVs" userLabel="showHideDateTime">
|
||||
<rect key="frame" x="0.0" y="0.0" width="69" height="49.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="69" id="ghQ-Qb-BBg"/>
|
||||
</constraints>
|
||||
<state key="normal">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="showHideDateTime:" destination="pad-g3-2YJ" eventType="touchUpInside" id="Ztw-z5-zlU"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a51-cR-7FE" userLabel="bubbleInfoContainer">
|
||||
<rect key="frame" x="8" y="10" width="61" height="39.5"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="61" id="fDy-iL-hrD"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="ezT-Dl-ESR" secondAttribute="trailing" constant="8" id="3Pd-Qy-Xva"/>
|
||||
<constraint firstAttribute="bottom" secondItem="tgO-Rv-C7R" secondAttribute="bottom" id="7C3-Tl-mMq"/>
|
||||
<constraint firstItem="tgO-Rv-C7R" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" constant="10" id="8Sy-eu-tYs"/>
|
||||
<constraint firstItem="a51-cR-7FE" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" constant="8" id="E3x-h8-GPF"/>
|
||||
<constraint firstItem="LVJ-Av-zVs" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" id="Hve-E3-z5N"/>
|
||||
<constraint firstAttribute="bottom" secondItem="LVJ-Av-zVs" secondAttribute="bottom" id="IKr-Dc-HKz"/>
|
||||
<constraint firstItem="ezT-Dl-ESR" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" constant="5" id="aHl-KA-68x"/>
|
||||
<constraint firstItem="a51-cR-7FE" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" constant="10" id="fQv-07-Pgx"/>
|
||||
<constraint firstItem="tgO-Rv-C7R" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="fCg-ju-gnG" secondAttribute="leading" constant="69" id="hwr-aa-TB4"/>
|
||||
<constraint firstItem="LVJ-Av-zVs" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" id="pYO-hi-P72"/>
|
||||
<constraint firstAttribute="bottom" secondItem="a51-cR-7FE" secondAttribute="bottom" id="viZ-Sx-3RW"/>
|
||||
<constraint firstAttribute="trailing" secondItem="tgO-Rv-C7R" secondAttribute="trailing" constant="51" id="xYz-lp-c7K"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="bubbleInfoContainer" destination="a51-cR-7FE" id="wrR-cU-DVm"/>
|
||||
<outlet property="bubbleInfoContainerTopConstraint" destination="fQv-07-Pgx" id="82c-KH-Wop"/>
|
||||
<outlet property="messageTextView" destination="tgO-Rv-C7R" id="LZ5-hQ-AbQ"/>
|
||||
<outlet property="msgTextViewBottomConstraint" destination="7C3-Tl-mMq" id="wCR-UC-iq8"/>
|
||||
<outlet property="msgTextViewLeadingConstraint" destination="hwr-aa-TB4" id="c9j-8p-cpx"/>
|
||||
<outlet property="msgTextViewMinHeightConstraint" destination="2xF-Uv-zZv" id="t2t-18-GqU"/>
|
||||
<outlet property="msgTextViewTopConstraint" destination="8Sy-eu-tYs" id="7yx-oJ-KBP"/>
|
||||
<outlet property="msgTextViewTrailingConstraint" destination="xYz-lp-c7K" id="ubt-P4-J2o"/>
|
||||
<outlet property="msgTextViewWidthConstraint" destination="ghN-E7-j4d" id="Dic-6M-yCy"/>
|
||||
<outlet property="pictureView" destination="ezT-Dl-ESR" id="YsO-Kp-xaD"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
-24
@@ -1,24 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomOutgoingTextMsgBubbleCell.h"
|
||||
|
||||
/**
|
||||
`MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell` displays outgoing message bubbles without user's name.
|
||||
*/
|
||||
@interface MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell : MXKRoomOutgoingTextMsgBubbleCell
|
||||
|
||||
@end
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
/*
|
||||
Copyright 2015 OpenMarket Ltd
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
#import "MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell.h"
|
||||
|
||||
@implementation MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell
|
||||
|
||||
@end
|
||||
-80
@@ -1,80 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableViewCell contentMode="scaleToFill" selectionStyle="none" indentationWidth="10" id="pad-g3-2YJ" customClass="MXKRoomOutgoingTextMsgWithoutSenderInfoBubbleCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="35"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="pad-g3-2YJ" id="fCg-ju-gnG">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="34.5"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" text="text message" translatesAutoresizingMaskIntoConstraints="NO" id="tgO-Rv-C7R" customClass="MXKMessageTextView">
|
||||
<rect key="frame" x="452" y="0.0" width="97" height="34.5"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="97" id="QpI-TQ-x5C"/>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="34" id="ur4-ZU-uyL"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="14"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
<dataDetectorType key="dataDetectorTypes" link="YES"/>
|
||||
</textView>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LVJ-Av-zVs" userLabel="showHideDateTime">
|
||||
<rect key="frame" x="0.0" y="0.0" width="69" height="34.5"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="69" id="ghQ-Qb-BBg"/>
|
||||
</constraints>
|
||||
<state key="normal">
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
<connections>
|
||||
<action selector="showHideDateTime:" destination="pad-g3-2YJ" eventType="touchUpInside" id="Ztw-z5-zlU"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="a51-cR-7FE" userLabel="bubbleInfoContainer">
|
||||
<rect key="frame" x="8" y="0.0" width="61" height="34.5"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="61" id="fDy-iL-hrD"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="tgO-Rv-C7R" secondAttribute="bottom" id="7C3-Tl-mMq"/>
|
||||
<constraint firstItem="tgO-Rv-C7R" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" id="8Sy-eu-tYs"/>
|
||||
<constraint firstItem="a51-cR-7FE" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" constant="8" id="E3x-h8-GPF"/>
|
||||
<constraint firstItem="LVJ-Av-zVs" firstAttribute="leading" secondItem="fCg-ju-gnG" secondAttribute="leading" id="Hve-E3-z5N"/>
|
||||
<constraint firstAttribute="bottom" secondItem="LVJ-Av-zVs" secondAttribute="bottom" id="IKr-Dc-HKz"/>
|
||||
<constraint firstItem="a51-cR-7FE" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" id="fQv-07-Pgx"/>
|
||||
<constraint firstItem="tgO-Rv-C7R" firstAttribute="leading" relation="greaterThanOrEqual" secondItem="fCg-ju-gnG" secondAttribute="leading" constant="69" id="hwr-aa-TB4"/>
|
||||
<constraint firstItem="LVJ-Av-zVs" firstAttribute="top" secondItem="fCg-ju-gnG" secondAttribute="top" id="pYO-hi-P72"/>
|
||||
<constraint firstAttribute="bottom" secondItem="a51-cR-7FE" secondAttribute="bottom" id="viZ-Sx-3RW"/>
|
||||
<constraint firstAttribute="trailing" secondItem="tgO-Rv-C7R" secondAttribute="trailing" constant="51" id="xYz-lp-c7K"/>
|
||||
</constraints>
|
||||
</tableViewCellContentView>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.0" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<connections>
|
||||
<outlet property="bubbleInfoContainer" destination="a51-cR-7FE" id="wrR-cU-DVm"/>
|
||||
<outlet property="bubbleInfoContainerTopConstraint" destination="fQv-07-Pgx" id="82c-KH-Wop"/>
|
||||
<outlet property="messageTextView" destination="tgO-Rv-C7R" id="LZ5-hQ-AbQ"/>
|
||||
<outlet property="msgTextViewBottomConstraint" destination="7C3-Tl-mMq" id="ReW-nS-1Jc"/>
|
||||
<outlet property="msgTextViewLeadingConstraint" destination="hwr-aa-TB4" id="c9j-8p-cpx"/>
|
||||
<outlet property="msgTextViewMinHeightConstraint" destination="ur4-ZU-uyL" id="gIe-dR-6cb"/>
|
||||
<outlet property="msgTextViewTopConstraint" destination="8Sy-eu-tYs" id="7yx-oJ-KBP"/>
|
||||
<outlet property="msgTextViewTrailingConstraint" destination="xYz-lp-c7K" id="ubt-P4-J2o"/>
|
||||
<outlet property="msgTextViewWidthConstraint" destination="QpI-TQ-x5C" id="6JK-pz-IWm"/>
|
||||
</connections>
|
||||
</tableViewCell>
|
||||
</objects>
|
||||
</document>
|
||||
@@ -115,7 +115,7 @@
|
||||
if (self->roomTopicListener && self.mxRoom)
|
||||
{
|
||||
MXWeakify(self);
|
||||
[self.mxRoom liveTimeline:^(MXEventTimeline *liveTimeline) {
|
||||
[self.mxRoom liveTimeline:^(id<MXEventTimeline> liveTimeline) {
|
||||
MXStrongifyAndReturnIfNil(self);
|
||||
|
||||
[liveTimeline removeListener:self->roomTopicListener];
|
||||
|
||||
Reference in New Issue
Block a user