mirror of
https://github.com/vector-im/element-ios.git
synced 2024-09-29 15:52:40 +00:00
Merge pull request #3741 from vector-im/release/1.0.15/release
Release 1.0.15
This commit is contained in:
commit
c1afce15b7
44 changed files with 770 additions and 427 deletions
32
CHANGES.rst
32
CHANGES.rst
|
@ -1,3 +1,34 @@
|
|||
Changes in 1.0.15 (2020-10-09)
|
||||
=================================================
|
||||
|
||||
✨ Features
|
||||
*
|
||||
|
||||
🙌 Improvements
|
||||
* Room: Make topic links tappable (#3713).
|
||||
* Room: Add more to long room topics (#3715).
|
||||
* Security screens: Update automatically shields when the trust changes.
|
||||
* Room: Add floating action button to invite members.
|
||||
* Pasteboard: Use MXKPasteboardManager.pasteboard on copy operations (#3732).
|
||||
|
||||
🐛 Bugfix
|
||||
* Push: Check crypto has keys to decrypt an event before decryption attempt, avoid sync loops on failure.
|
||||
|
||||
⚠️ API Changes
|
||||
*
|
||||
|
||||
🗣 Translations
|
||||
*
|
||||
|
||||
🧱 Build
|
||||
*
|
||||
|
||||
Others
|
||||
*
|
||||
|
||||
Improvements:
|
||||
* Upgrade MatrixKit version ([v0.12.23](https://github.com/matrix-org/matrix-ios-kit/releases/tag/v0.12.23)).
|
||||
|
||||
Changes in 1.0.14 (2020-10-02)
|
||||
=================================================
|
||||
|
||||
|
@ -14,6 +45,7 @@ Changes in 1.0.14 (2020-10-02)
|
|||
* Fix "Unable to open the link" error when using non-Safari browsers (#3673).
|
||||
* Biometrics: Handle retry case.
|
||||
* Room: Remove membership events from room creation modal (#3679).
|
||||
* PIN: Fix layout on small screens.
|
||||
|
||||
⚠️ API Changes
|
||||
*
|
||||
|
|
10
Podfile
10
Podfile
|
@ -11,7 +11,7 @@ use_frameworks!
|
|||
# - `{ {kit spec hash} => {sdk spec hash}` to depend on specific pod options (:git => …, :podspec => …) for each repo. Used by Fastfile during CI
|
||||
#
|
||||
# Warning: our internal tooling depends on the name of this variable name, so be sure not to change it
|
||||
$matrixKitVersion = '= 0.12.22'
|
||||
$matrixKitVersion = '= 0.12.23'
|
||||
# $matrixKitVersion = :local
|
||||
# $matrixKitVersion = {'develop' => 'develop'}
|
||||
|
||||
|
@ -74,6 +74,7 @@ abstract_target 'RiotPods' do
|
|||
pod 'KTCenterFlowLayout', '~> 1.3.1'
|
||||
pod 'ZXingObjC', '~> 3.6.5'
|
||||
pod 'FlowCommoniOS', '~> 1.8.7'
|
||||
pod 'ReadMoreTextView', '~> 3.0.1'
|
||||
|
||||
target 'RiotTests' do
|
||||
inherit! :search_paths
|
||||
|
@ -102,7 +103,12 @@ post_install do |installer|
|
|||
# Because the WebRTC pod (included by the JingleCallStack pod) does not support it.
|
||||
# Plus the app does not enable it
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
||||
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
||||
|
||||
# Force ReadMoreTextView to use Swift 5.2 version (as there is no code changes to perform)
|
||||
if target.name.include? 'ReadMoreTextView'
|
||||
config.build_settings['SWIFT_VERSION'] = '5.2'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7277,7 +7277,7 @@
|
|||
CODE_SIGN_IDENTITY = "iPhone Developer";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
CURRENT_PROJECT_VERSION = 1.0.14;
|
||||
CURRENT_PROJECT_VERSION = 1.0.15;
|
||||
DEFINES_MODULE = YES;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
|
@ -7297,7 +7297,7 @@
|
|||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 1.0.14;
|
||||
MARKETING_VERSION = 1.0.15;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
|
@ -7336,7 +7336,7 @@
|
|||
CODE_SIGN_IDENTITY = "iPhone Distribution";
|
||||
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution";
|
||||
COPY_PHASE_STRIP = YES;
|
||||
CURRENT_PROJECT_VERSION = 1.0.14;
|
||||
CURRENT_PROJECT_VERSION = 1.0.15;
|
||||
DEFINES_MODULE = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
|
@ -7349,7 +7349,7 @@
|
|||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
|
||||
MARKETING_VERSION = 1.0.14;
|
||||
MARKETING_VERSION = 1.0.15;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_COMPILATION_MODE = wholemodule;
|
||||
|
|
23
Riot/Assets/Images.xcassets/Room/add_member_floating_action.imageset/Contents.json
vendored
Normal file
23
Riot/Assets/Images.xcassets/Room/add_member_floating_action.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "FAB.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "FAB@2x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "FAB@3x.png",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
BIN
Riot/Assets/Images.xcassets/Room/add_member_floating_action.imageset/FAB.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Room/add_member_floating_action.imageset/FAB.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
BIN
Riot/Assets/Images.xcassets/Room/add_member_floating_action.imageset/FAB@2x.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Room/add_member_floating_action.imageset/FAB@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 20 KiB |
BIN
Riot/Assets/Images.xcassets/Room/add_member_floating_action.imageset/FAB@3x.png
vendored
Normal file
BIN
Riot/Assets/Images.xcassets/Room/add_member_floating_action.imageset/FAB@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 23 KiB |
|
@ -1,5 +1,5 @@
|
|||
/* New message from a specific person, not referencing a room */
|
||||
"MSG_FROM_USER" = "Missatge de %@";
|
||||
"MSG_FROM_USER" = "%@ ha enviat un missatge";
|
||||
/* New message from a specific person in a named room */
|
||||
"MSG_FROM_USER_IN_ROOM" = "%@ publicat a %@";
|
||||
/* New message from a specific person, not referencing a room. Content included. */
|
||||
|
@ -11,7 +11,7 @@
|
|||
/* New action message from a specific person in a named room. */
|
||||
"ACTION_FROM_USER_IN_ROOM" = "%@: * %@ %@";
|
||||
/* New action message from a specific person, not referencing a room. */
|
||||
"IMAGE_FROM_USER" = "%@ t'ha enviat una foto %@";
|
||||
"IMAGE_FROM_USER" = "%@ ha enviat una foto %@";
|
||||
/* New action message from a specific person in a named room. */
|
||||
"IMAGE_FROM_USER_IN_ROOM" = "%@ ha publicat una foto %@ a %@";
|
||||
/* Multiple unread messages in a room */
|
||||
|
@ -50,3 +50,14 @@
|
|||
"SINGLE_UNREAD_IN_ROOM" = "Has rebut un missatge a %@";
|
||||
/* A single unread message */
|
||||
"SINGLE_UNREAD" = "Has rebut un missatge";
|
||||
/* Message title for a specific person in a named room */
|
||||
"MSG_FROM_USER_IN_ROOM_TITLE" = "%@ a %@";
|
||||
/* Sticker from a specific person, not referencing a room. */
|
||||
"STICKER_FROM_USER" = "%@ t’ha enviat una enganxina";
|
||||
/* New message indicator on unknown room */
|
||||
"MESSAGE" = "Missatge";
|
||||
/* New message indicator from a DM */
|
||||
"MESSAGE_FROM_X" = "Missatge de %@";
|
||||
/* New message indicator on a room */
|
||||
"MESSAGE_IN_X" = "Missatge a %@";
|
||||
"KEY_VERIFICATION_REQUEST_FROM_USER" = "%@ vol verificar";
|
||||
|
|
|
@ -552,3 +552,18 @@
|
|||
// Re-request confirmation dialog
|
||||
"rerequest_keys_alert_title" = "Sol·licitud enviada";
|
||||
"rerequest_keys_alert_message" = "Inicia Element en un altre dispositiu que pugui desxifrar el missatge per que pugui enviar les claus a aquest dispositiu.";
|
||||
// String for App Store
|
||||
"store_short_description" = "Xat/VoIP segur i descentralitzat";
|
||||
"close" = "Tanca";
|
||||
"skip" = "Salta";
|
||||
"joined" = "Unit";
|
||||
"switch" = "Canvia";
|
||||
"more" = "Més";
|
||||
// Accessibility
|
||||
"accessibility_checkbox_label" = "casella de selecció";
|
||||
// MARK: Clients
|
||||
"client_desktop_name" = "Element Escriptori";
|
||||
"client_web_name" = "Element Web";
|
||||
"client_ios_name" = "Element iOS";
|
||||
"client_android_name" = "Element Android";
|
||||
"auth_login_single_sign_on" = "Inicia sessió amb inici senzill";
|
||||
|
|
|
@ -1187,7 +1187,7 @@
|
|||
"pin_protection_choose_pin_welcome_after_login" = "Willkommen zurück.";
|
||||
"pin_protection_choose_pin_welcome_after_register" = "Willkommen.";
|
||||
"pin_protection_not_allowed_pin" = "Aus Sicherheitsgründen ist diese PIN nicht verfügbar. Bitte versuche es mit einer anderen PIN";
|
||||
"pin_protection_explanatory" = "PINs helfen dein Profil, deine Nachrichten und Kontakte so zu sichern, dass nur du Zugriff auf sie hast.";
|
||||
"pin_protection_explanatory" = "Das Einrichten einer PIN schützt Daten wie Nachrichten und Kontakten so, dass nur du Zugriff auf sie hast, indem du die PIN beim Starten der App eingibst.";
|
||||
"searchable_directory_create_new_room" = "Erstelle einen neuen Raum";
|
||||
"searchable_directory_x_network" = "%@ Netzwerk";
|
||||
"searchable_directory_search_placeholder" = "Name oder ID";
|
||||
|
@ -1210,3 +1210,20 @@
|
|||
"room_info_list_one_member" = "1 Mitglied";
|
||||
"room_info_list_several_members" = "%@ Mitglieder";
|
||||
"room_info_list_section_other" = "Sonstige";
|
||||
"room_participants_leave_prompt_title_for_dm" = "Verlassen";
|
||||
"room_participants_filter_room_members_for_dm" = "Mitglieder filtern";
|
||||
"room_participants_security_information_room_not_encrypted_for_dm" = "Die Nachrichten hier sind nicht Ende-zu-Ende verschlüsselt.";
|
||||
"room_participants_leave_prompt_msg_for_dm" = "Bist du sicher, dass du die Konversation verlassen möchtest?";
|
||||
"room_participants_security_information_room_encrypted_for_dm" = "Nachrichten hier sind Ende-zu-Ende verschlüsselt.\n\nDeine Nachrichten sind mit digitalen Schlüsseln gesichert, nur du und der/die Empfänger!n haben die einzigen Schlüssel, um jene zu entsperren.";
|
||||
"room_details_title_for_dm" = "Details";
|
||||
"room_details_photo_for_dm" = "Bild";
|
||||
"room_details_room_name_for_dm" = "Name";
|
||||
"room_details_access_section_for_dm" = "Wer hat Zugriff hierauf?";
|
||||
"room_details_access_section_anyone_apart_from_guest_for_dm" = "Alle, die den Link kennen (ausgenommen Gäste)";
|
||||
"room_details_access_section_anyone_for_dm" = "Alle, die den Link kennen (auch Gäste)";
|
||||
"room_details_access_section_directory_toggle_for_dm" = "Im Raum-Verzeichnis auflisten";
|
||||
"room_details_no_local_addresses_for_dm" = "Keine lokalen Adressen vorhanden";
|
||||
"room_details_advanced_room_id_for_dm" = "ID:";
|
||||
"room_details_advanced_e2e_encryption_enabled_for_dm" = "Verschlüsselung ist hier aktiviert";
|
||||
"room_details_advanced_e2e_encryption_disabled_for_dm" = "Verschlüsselung ist hier nicht aktiviert.";
|
||||
"pin_protection_kick_user_alert_message" = "Zu viele Fehler. Du wurdest ausgeloggt";
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
"joined" = "Joined";
|
||||
"switch" = "Switch";
|
||||
"more" = "More";
|
||||
"less" = "Less";
|
||||
|
||||
// Accessibility
|
||||
"accessibility_checkbox_label" = "checkbox";
|
||||
|
|
|
@ -1147,7 +1147,7 @@
|
|||
"pin_protection_choose_pin_welcome_after_login" = "Tere tulemast tagasi.";
|
||||
"pin_protection_choose_pin_welcome_after_register" = "Tere tulemast.";
|
||||
"pin_protection_not_allowed_pin" = "Turvapõhjustel seda PIN-kooi ei saa kasutada. Palun vali mõnu muu PIN-kood";
|
||||
"pin_protection_explanatory" = "PIN-kood aitab tagada, et vaid sina ise pääsed ligi oma profiilile, sõnumitele ja kontaktidele.";
|
||||
"pin_protection_explanatory" = "PIN-koodi seadistamine aitab tagada, et vaid sina ise pääsed ligi oma profiilile, sõnumitele ja kontaktidele, kui sisestad PIN-koodi rakenduse käivitamisel.";
|
||||
"searchable_directory_create_new_room" = "Loo uus jututuba";
|
||||
"searchable_directory_x_network" = "%@ võrk";
|
||||
"searchable_directory_search_placeholder" = "Nimi või Matrix'i tunnus";
|
||||
|
@ -1170,3 +1170,20 @@
|
|||
"room_info_list_one_member" = "1 liige";
|
||||
"room_info_list_several_members" = "%@ liiget";
|
||||
"room_info_list_section_other" = "Muud";
|
||||
"room_participants_leave_prompt_title_for_dm" = "Lahku";
|
||||
"room_participants_leave_prompt_msg_for_dm" = "Kas oled kindel, et soovid lahkuda jututoast?";
|
||||
"room_participants_filter_room_members_for_dm" = "Filtreeri jututoa liikmeid";
|
||||
"room_participants_security_information_room_not_encrypted_for_dm" = "See jututuba ei ole läbivalt krüptitud.";
|
||||
"room_participants_security_information_room_encrypted_for_dm" = "Sõnumid siin jututoas kasutavad läbivat krüptimist. \n \nSinu sõnumid on turvatud ning ainult sinul ja saaja(te)l on unikaalsed võtmed selliste sõnumite lugemiseks.";
|
||||
"room_details_title_for_dm" = "Jututoa üksikasjad";
|
||||
"room_details_photo_for_dm" = "Jututoa foto";
|
||||
"room_details_room_name_for_dm" = "Nimi";
|
||||
"room_details_access_section_for_dm" = "Kes pääsevad ligi siia jututuppa?";
|
||||
"room_details_access_section_anyone_apart_from_guest_for_dm" = "Kõik, kes teavad jututoa viidet, välja arvatud külalised";
|
||||
"room_details_access_section_anyone_for_dm" = "Kõik, kes teavad jututoa viidet, kaasa arvatud külalised";
|
||||
"room_details_access_section_directory_toggle_for_dm" = "Näita seda jututuba jututubade kataloogis";
|
||||
"room_details_no_local_addresses_for_dm" = "Sellel jututoal puuduvad kohalikud aadressid";
|
||||
"room_details_advanced_room_id_for_dm" = "Jututoa tunnus:";
|
||||
"room_details_advanced_e2e_encryption_enabled_for_dm" = "Krüptimine on selles jututoas kasutusel";
|
||||
"room_details_advanced_e2e_encryption_disabled_for_dm" = "Krüptimine ei ole selles jututoas kasutusel.";
|
||||
"pin_protection_kick_user_alert_message" = "Liiga palju vigu PIN-koodi sisestamisel ning sa oled nüüd välja logitud";
|
||||
|
|
|
@ -353,7 +353,7 @@
|
|||
"settings_crypto_blacklist_unverified_devices" = "Csak ellenőrzött munkameneteknek titkosít";
|
||||
"settings_deactivate_my_account" = "Felhasználói fiókom felfüggesztése";
|
||||
"room_details_people" = "Tagok";
|
||||
"room_details_files" = "Fájlok";
|
||||
"room_details_files" = "Feltöltések";
|
||||
"room_details_settings" = "Beállítások";
|
||||
"room_details_photo" = "Szoba képe";
|
||||
"room_details_room_name" = "Szoba neve";
|
||||
|
@ -1174,7 +1174,7 @@
|
|||
"external_link_confirmation_title" = "Ezt a hivatkozást ellenőrizd le még egyszer";
|
||||
"external_link_confirmation_message" = "%@ hivatkozás egy másik oldalra visz: %@ \n \nFolytatod?";
|
||||
"major_update_information" = "Izgatottan jelentjük, hogy megváltoztattuk a nevünket! Az alkalmazásod friss és be vagy jelentkezve a fiókodba.";
|
||||
"pin_protection_choose_pin" = "A biztonság érdekében válassz egy PIN kódot";
|
||||
"pin_protection_choose_pin" = "A biztonság érdekében adj meg egy PIN kódot";
|
||||
"pin_protection_confirm_pin" = "Erősítsd meg a PIN kódot";
|
||||
"pin_protection_confirm_pin_to_disable" = "A PIN letiltásához írd be a PIN kódot";
|
||||
"pin_protection_enter_pin" = "Add meg a PIN kódot";
|
||||
|
@ -1205,3 +1205,48 @@
|
|||
"biometrics_cant_unlocked_alert_message_retry" = "Újra";
|
||||
"biometrics_desetup_subtitle" = " ";
|
||||
"device_verification_self_verify_wait_recover_secrets_checking_availability" = "További hitelesítési lehetőségek keresése …";
|
||||
"joined" = "Csatlakozott";
|
||||
"switch" = "Cserél";
|
||||
"more" = "További";
|
||||
"room_participants_leave_prompt_title_for_dm" = "Elhagy";
|
||||
"room_participants_leave_prompt_msg_for_dm" = "Biztos, hogy ki akarsz lépni?";
|
||||
"room_participants_filter_room_members_for_dm" = "Tagok szűrése";
|
||||
"room_participants_security_information_room_not_encrypted_for_dm" = "Itt az üzenetek nincsenek végponttól végpontig titkosítva.";
|
||||
"room_participants_security_information_room_encrypted_for_dm" = "Itt az üzenetek végponttól végpontig titkosítva vannak. \n \nAz üzeneteidet titkosítással vannak biztosítva és csak neked és a címzetteknek van meg a kulcs hozzá.";
|
||||
"room_details_title_for_dm" = "Részletek";
|
||||
"room_details_photo_for_dm" = "Fotó";
|
||||
"room_details_room_name_for_dm" = "Név";
|
||||
"room_details_access_section_for_dm" = "Ki tud hozzáférni ehhez?";
|
||||
"room_details_access_section_anyone_apart_from_guest_for_dm" = "Bárki aki ismeri a linket, a vendégeket leszámítva";
|
||||
"room_details_access_section_anyone_for_dm" = "Bárki aki ismeri a linket, beleszámítva a vendégek";
|
||||
"room_details_access_section_directory_toggle_for_dm" = "Megjelenik a szobák listájában";
|
||||
"room_details_no_local_addresses_for_dm" = "Ennek nincs helyi címe";
|
||||
"room_details_advanced_room_id_for_dm" = "Azon.:";
|
||||
"room_details_advanced_e2e_encryption_enabled_for_dm" = "A titkosítás bekapcsolva";
|
||||
"room_details_advanced_e2e_encryption_disabled_for_dm" = "Itt a titkosítás nincs bekapcsolva.";
|
||||
"pin_protection_choose_pin_welcome_after_login" = "Üdv újra.";
|
||||
"pin_protection_choose_pin_welcome_after_register" = "Üdv!";
|
||||
"pin_protection_not_allowed_pin" = "Ez a PIN biztonsági okokból nem használható. Kérlek adj meg egy másik PIN-t";
|
||||
"pin_protection_explanatory" = "A PIN beállításával védheted az olyan dolgokat, mint pl. üzenetek és névjegyek, hogy csak te férhessél hozzájuk az alkalmazás indulásakor megadott PIN kóddal.";
|
||||
"pin_protection_kick_user_alert_message" = "Túl sok a hiba, ki lettél jelentkeztetve";
|
||||
"searchable_directory_create_new_room" = "Új szoba készítése";
|
||||
"searchable_directory_x_network" = "%@ hálózat";
|
||||
"searchable_directory_search_placeholder" = "Név vagy azon.";
|
||||
"create_room_title" = "Új szoba";
|
||||
"create_room_section_header_name" = "Szoba neve";
|
||||
"create_room_placeholder_name" = "Név";
|
||||
"create_room_section_header_topic" = "Szoba témája (nem kötelező)";
|
||||
"create_room_placeholder_topic" = "Téma";
|
||||
"create_room_section_header_encryption" = "Szoba titkosítása";
|
||||
"create_room_enable_encryption" = "Titkosítás engedélyezése";
|
||||
"create_room_section_footer_encryption" = "A titkosítást ezután nem lehet kikapcsolni.";
|
||||
"create_room_section_header_type" = "Szoba típusa";
|
||||
"create_room_type_private" = "Privát szoba";
|
||||
"create_room_type_public" = "Nyilvános szoba";
|
||||
"create_room_section_footer_type" = "Emberek csak meghívóval csatlakozhatnak a privát szobához.";
|
||||
"create_room_show_in_directory" = "A szoba megjelenítése a listában";
|
||||
"create_room_section_header_address" = "Szoba címe";
|
||||
"create_room_placeholder_address" = "#testroom:matrix.org";
|
||||
"room_info_list_one_member" = "1 tag";
|
||||
"room_info_list_several_members" = "%@ tag";
|
||||
"room_info_list_section_other" = "Más";
|
||||
|
|
|
@ -1181,7 +1181,7 @@
|
|||
"pin_protection_choose_pin_welcome_after_login" = "Bentornato/a.";
|
||||
"pin_protection_choose_pin_welcome_after_register" = "Benvenuti.";
|
||||
"pin_protection_not_allowed_pin" = "Per motivi di sicurezza, questo PIN non è disponibile. Provane un altro";
|
||||
"pin_protection_explanatory" = "I PIN aiutano a tenere sicuri il tuo profilo, i messaggi e i contatti, in modo che solo tu possa vederli.";
|
||||
"pin_protection_explanatory" = "L'impostazione di un PIN ti permette di proteggere dati come messaggi e contatti, in modo che solo tu possa vederli inserendo il PIN all'apertura dell'app.";
|
||||
"searchable_directory_create_new_room" = "Crea una nuova stanza";
|
||||
"searchable_directory_x_network" = "Rete %@";
|
||||
"searchable_directory_search_placeholder" = "Nome o ID";
|
||||
|
@ -1204,3 +1204,20 @@
|
|||
"room_info_list_one_member" = "1 membro";
|
||||
"room_info_list_several_members" = "%@ membri";
|
||||
"room_info_list_section_other" = "Altro";
|
||||
"room_participants_leave_prompt_title_for_dm" = "Esci";
|
||||
"room_participants_leave_prompt_msg_for_dm" = "Vuoi veramente uscire?";
|
||||
"room_participants_filter_room_members_for_dm" = "Filtra membri";
|
||||
"room_participants_security_information_room_not_encrypted_for_dm" = "I messaggi qui non sono cifrati end-to-end.";
|
||||
"room_participants_security_information_room_encrypted_for_dm" = "I messaggi qui sono cifrati end-to-end. \n \nI tuoi messaggi sono protetti con lucchetti e solo tu e il destinatario avete le chiavi univoche per sbloccarli.";
|
||||
"room_details_title_for_dm" = "Dettagli";
|
||||
"room_details_photo_for_dm" = "Foto";
|
||||
"room_details_room_name_for_dm" = "Nome";
|
||||
"room_details_access_section_for_dm" = "Chi può accedervi?";
|
||||
"room_details_access_section_anyone_apart_from_guest_for_dm" = "Chiunque conosca il link, eccetto gli ospiti";
|
||||
"room_details_access_section_anyone_for_dm" = "Chiunque conosca il link, compresi gli ospiti";
|
||||
"room_details_access_section_directory_toggle_for_dm" = "Mostra nell'elenco delle stanze";
|
||||
"room_details_no_local_addresses_for_dm" = "Non ha indirizzi locali";
|
||||
"room_details_advanced_room_id_for_dm" = "ID:";
|
||||
"room_details_advanced_e2e_encryption_enabled_for_dm" = "La crittografia è attiva";
|
||||
"room_details_advanced_e2e_encryption_disabled_for_dm" = "La crittografia non è attiva.";
|
||||
"pin_protection_kick_user_alert_message" = "Troppi errori, sei stato disconnesso";
|
||||
|
|
|
@ -55,3 +55,9 @@
|
|||
/* Incoming named video conference invite from a specific person */
|
||||
"VIDEO_CONF_NAMED_FROM_USER" = "Grupowe połączenie wideo z %@: '%@'";
|
||||
"KEY_VERIFICATION_REQUEST_FROM_USER" = "%@ wymaga weryfikacji";
|
||||
/* New message indicator on unknown room */
|
||||
"MESSAGE" = "Wiadomość";
|
||||
/* New message indicator from a DM */
|
||||
"MESSAGE_FROM_X" = "Wiadomość od %@";
|
||||
/* New message indicator on a room */
|
||||
"MESSAGE_IN_X" = "Wiadomość w %@";
|
||||
|
|
|
@ -1192,7 +1192,7 @@
|
|||
"pin_protection_choose_pin_welcome_after_login" = "С возвращением.";
|
||||
"pin_protection_choose_pin_welcome_after_register" = "Добро пожаловать.";
|
||||
"pin_protection_not_allowed_pin" = "По соображениям безопасности этот PIN-код недоступен. Пожалуйста, попробуйте другой PIN-код";
|
||||
"pin_protection_explanatory" = "PIN-коды помогают защитить ваш профиль, сообщения и контакты, поэтому только вы можете получить к ним доступ.";
|
||||
"pin_protection_explanatory" = "Установка PIN-кода позволяет защитить такие данные, как сообщения и контакты, поэтому только вы можете получить к ним доступ, введя PIN-код в начале приложения.";
|
||||
"searchable_directory_create_new_room" = "Создать новую комнату";
|
||||
"searchable_directory_x_network" = "%@ Сеть";
|
||||
"searchable_directory_search_placeholder" = "Имя или ID";
|
||||
|
@ -1231,3 +1231,4 @@
|
|||
"room_details_advanced_room_id_for_dm" = "ID:";
|
||||
"room_details_advanced_e2e_encryption_enabled_for_dm" = "Шифрование включено";
|
||||
"room_details_advanced_e2e_encryption_disabled_for_dm" = "Шифрование не включено.";
|
||||
"pin_protection_kick_user_alert_message" = "Слишком много ошибок, вы вышли из системы";
|
||||
|
|
|
@ -1193,7 +1193,7 @@
|
|||
"pin_protection_choose_pin_welcome_after_login" = "Mirë se u kthyet.";
|
||||
"pin_protection_choose_pin_welcome_after_register" = "Mirë se vini.";
|
||||
"pin_protection_not_allowed_pin" = "Për arsye sigurie, ky PIN s’është i passhëm. Ju lutemi, provoni një PIN tjetër";
|
||||
"pin_protection_explanatory" = "PIN-et ndihmojnë për të mbajtur të siguruar profilin, mesazhet dhe kontaktet tuaja, që kështu të mund t’i përdorni.";
|
||||
"pin_protection_explanatory" = "Ujdisja e një PIN-it ju lejon të mbroni të dhëna të tilla si, mesazhe dhe kontakte, që kështu të mund t’i përdorni duke dhënë PIN-in gjatë nisjes së aplikacionit.";
|
||||
"searchable_directory_create_new_room" = "Krijoni një dhomë të re";
|
||||
"searchable_directory_x_network" = "Rrjet %@";
|
||||
"searchable_directory_search_placeholder" = "Emër ose ID";
|
||||
|
@ -1216,3 +1216,20 @@
|
|||
"room_info_list_one_member" = "1 anëtar";
|
||||
"room_info_list_several_members" = "%@ anëtarë";
|
||||
"room_info_list_section_other" = "Tjetër";
|
||||
"room_participants_leave_prompt_title_for_dm" = "Ikni";
|
||||
"room_participants_leave_prompt_msg_for_dm" = "Jeni i sigurt se doni të ikni?";
|
||||
"room_participants_filter_room_members_for_dm" = "Filtroni anëtarë";
|
||||
"room_participants_security_information_room_not_encrypted_for_dm" = "Mesazhet këtu s’janë të fshehtëzuar skaj-më-skaj.";
|
||||
"room_participants_security_information_room_encrypted_for_dm" = "Mesazhet këtu janë të fshehtëzuar skaj-më-skaj.\n\nMesazhet tuaj janë të siguruar me kyçe dhe vetëm ju dhe marrësi keni kyçet unikë për shkyçjen e tyre.";
|
||||
"room_details_title_for_dm" = "Hollësi";
|
||||
"room_details_photo_for_dm" = "Foto";
|
||||
"room_details_room_name_for_dm" = "Emër";
|
||||
"room_details_access_section_for_dm" = "Kush mund të përdorë këtë?";
|
||||
"room_details_access_section_anyone_apart_from_guest_for_dm" = "Cilido që njeh lidhjen, hiq vizitorë";
|
||||
"room_details_access_section_anyone_for_dm" = "Cilido që njeh lidhjen, përfshi vizitorë";
|
||||
"room_details_access_section_directory_toggle_for_dm" = "Paraqit ç’ka lista e dhomave";
|
||||
"room_details_no_local_addresses_for_dm" = "Kjo s’ka adresa vendore";
|
||||
"room_details_advanced_room_id_for_dm" = "ID:";
|
||||
"room_details_advanced_e2e_encryption_enabled_for_dm" = "Këtu fshehtëzimi është i aktivizuar";
|
||||
"room_details_advanced_e2e_encryption_disabled_for_dm" = "Këtu fshehtëzimi s’është i aktivizuar.";
|
||||
"pin_protection_kick_user_alert_message" = "Shumë gabime, u bë nxjerrja juaj jashtë";
|
||||
|
|
|
@ -462,7 +462,7 @@
|
|||
"identity_server_settings_alert_no_terms_title" = "Identitetsservern har inga användarvillkor";
|
||||
"identity_server_settings_alert_change_title" = "Byt identitetsserver";
|
||||
"room_details_people" = "Medlemmar";
|
||||
"room_details_files" = "Filer";
|
||||
"room_details_files" = "Uppladdningar";
|
||||
"room_details_settings" = "Inställningar";
|
||||
"room_details_room_name" = "Rumsnamn";
|
||||
"room_details_topic" = "Ämne";
|
||||
|
@ -1111,7 +1111,7 @@
|
|||
"major_update_information" = "Vi är glada att meddela att vi har bytt namn! Din app är uppdaterad och du är inloggad på ditt konto.";
|
||||
"major_update_learn_more_action" = "Lär dig mer";
|
||||
"major_update_done_action" = "Förstått";
|
||||
"pin_protection_choose_pin" = "Väl en PIN-kod för säkerhet";
|
||||
"pin_protection_choose_pin" = "Skapa en PIN-kod för säkerhet";
|
||||
"pin_protection_confirm_pin" = "Bekräfta din PIN-kod";
|
||||
"pin_protection_confirm_pin_to_disable" = "Bekräfta PIN-kod för att inaktivera PIN-kod";
|
||||
"pin_protection_enter_pin" = "Ange din PIN-kod";
|
||||
|
@ -1140,3 +1140,49 @@
|
|||
"biometrics_cant_unlocked_alert_message_x" = "För att låsa upp, använd %@ eller logga in igen och aktivera %@ igen";
|
||||
"biometrics_cant_unlocked_alert_message_login" = "Logga in igen";
|
||||
"biometrics_cant_unlocked_alert_message_retry" = "Försök igen";
|
||||
"joined" = "Gått med";
|
||||
"switch" = "Byt";
|
||||
"more" = "Mer";
|
||||
"room_participants_leave_prompt_title_for_dm" = "Lämna";
|
||||
"room_participants_leave_prompt_msg_for_dm" = "Är du säker på att du vill lämna?";
|
||||
"room_participants_filter_room_members_for_dm" = "Filtrera medlemmar";
|
||||
"room_participants_security_information_room_not_encrypted_for_dm" = "Meddelanden här är inte totalsträckskrypterade.";
|
||||
"room_participants_security_information_room_encrypted_for_dm" = "Meddelanden här är totalsträckskrypterade.\n\nDina meddelanden är säkrade med lås och endast du och mottagaren har de unika nycklarna för att låsa upp dem.";
|
||||
"room_details_title_for_dm" = "Detaljer";
|
||||
"room_details_photo_for_dm" = "Bild";
|
||||
"room_details_room_name_for_dm" = "Namn";
|
||||
"room_details_access_section_for_dm" = "Vem kan komma åt detta?";
|
||||
"room_details_access_section_anyone_apart_from_guest_for_dm" = "Alla som har länken, förutom gäster";
|
||||
"room_details_access_section_anyone_for_dm" = "Alla som har länken, inklusive gäster";
|
||||
"room_details_access_section_directory_toggle_for_dm" = "Lista i rumskatalogen";
|
||||
"room_details_no_local_addresses_for_dm" = "Detta har inga lokala adresser";
|
||||
"room_details_advanced_room_id_for_dm" = "ID:";
|
||||
"room_details_advanced_e2e_encryption_enabled_for_dm" = "Kryptering är aktiverad här";
|
||||
"room_details_advanced_e2e_encryption_disabled_for_dm" = "Kryptering är inte aktiverad här.";
|
||||
"device_verification_self_verify_wait_recover_secrets_checking_availability" = "Letar efter andra verifieringsfunktioner…";
|
||||
"pin_protection_choose_pin_welcome_after_login" = "Välkommen tillbaka.";
|
||||
"pin_protection_choose_pin_welcome_after_register" = "Välkommen.";
|
||||
"pin_protection_not_allowed_pin" = "Av säkerhetsskäl är den här PIN-koden inte tillgänglig. Vänligen pröva en annan PIN-kod";
|
||||
"pin_protection_explanatory" = "Att ställa in en PIN-kod låter dig skydda data som meddelanden och kontakter så att endast du kan komma åt dem genom att slå in koden när du startar appen.";
|
||||
"pin_protection_kick_user_alert_message" = "För många fel, du har loggats ut";
|
||||
"searchable_directory_create_new_room" = "Skapa ett nytt rum";
|
||||
"searchable_directory_x_network" = "%@-nätverk";
|
||||
"searchable_directory_search_placeholder" = "Namn eller ID";
|
||||
"create_room_title" = "Nytt rum";
|
||||
"create_room_section_header_name" = "Rumsnamn";
|
||||
"create_room_placeholder_name" = "Namn";
|
||||
"create_room_section_header_topic" = "Rumsämne (valfritt)";
|
||||
"create_room_placeholder_topic" = "Ämne";
|
||||
"create_room_section_header_encryption" = "Rumskryptering";
|
||||
"create_room_enable_encryption" = "Aktivera kryptering";
|
||||
"create_room_section_footer_encryption" = "Kryptering kan inte inaktiveras igen.";
|
||||
"create_room_section_header_type" = "Rumstyp";
|
||||
"create_room_type_private" = "Privat rum";
|
||||
"create_room_type_public" = "Offentligt rum";
|
||||
"create_room_section_footer_type" = "Personer kan endast gå med i ett privat rum om de bjuds in.";
|
||||
"create_room_show_in_directory" = "Visa rummet i katalogen";
|
||||
"create_room_section_header_address" = "Rumsadress";
|
||||
"create_room_placeholder_address" = "#testrum:matrix.org";
|
||||
"room_info_list_one_member" = "1 medlem";
|
||||
"room_info_list_several_members" = "%@ medlemmar";
|
||||
"room_info_list_section_other" = "Andra";
|
||||
|
|
|
@ -1469,6 +1469,28 @@
|
|||
SOFTWARE.
|
||||
<br/><br/>
|
||||
</li>
|
||||
<li>
|
||||
<b>ReadMoreTextView</b> (<a href="https://github.com/ilyapuchka/ReadMoreTextView">https://github.com/ilyapuchka/ReadMoreTextView</a>)
|
||||
<br/><br/>UITextView subclass with "read more"/"read less" capabilities and UITextView extensions to handle touches in characters range.
|
||||
<br/><br/>It is released under the MIT license.
|
||||
<br/><br/>Copyright (c) 2015-2016 Ilya Puchka
|
||||
<br/><br/>Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
<br/><br/>The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
<br/><br/>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
<br/><br/>
|
||||
</li>
|
||||
</ul>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -28,5 +28,37 @@ extension UITableView {
|
|||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/// Since UITableView does not manage Auto Layout for header, it'd be appropriate calling this after tableView bounds change
|
||||
@objc func vc_relayoutHeaderView() {
|
||||
guard let headerView = tableHeaderView else { return }
|
||||
let height = ceil(headerView.systemLayoutSizeFitting(CGSize(width: bounds.width, height: 0),
|
||||
withHorizontalFittingPriority: .required,
|
||||
verticalFittingPriority: .fittingSizeLevel).height)
|
||||
|
||||
// compare heights to avoid infinite loop
|
||||
if height != headerView.frame.height {
|
||||
var headerFrame = headerView.frame
|
||||
headerFrame.size.height = height
|
||||
headerView.frame = headerFrame
|
||||
tableHeaderView = headerView
|
||||
}
|
||||
}
|
||||
|
||||
/// Since UITableView does not manage Auto Layout for footer, it'd be appropriate calling this after tableView bounds change
|
||||
@objc func vc_relayoutFooterView() {
|
||||
guard let footerView = tableFooterView else { return }
|
||||
let height = ceil(footerView.systemLayoutSizeFitting(CGSize(width: bounds.width, height: 0),
|
||||
withHorizontalFittingPriority: .required,
|
||||
verticalFittingPriority: .fittingSizeLevel).height)
|
||||
|
||||
// compare heights to avoid infinite loop
|
||||
if height != footerView.frame.height {
|
||||
var headerFrame = footerView.frame
|
||||
headerFrame.size.height = height
|
||||
footerView.frame = headerFrame
|
||||
tableFooterView = footerView
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,12 @@ import UIKit
|
|||
|
||||
extension UIViewController {
|
||||
|
||||
private enum UIViewControllerConstants {
|
||||
static let fabButtonSize = CGSize(width: 78, height: 78)
|
||||
static let fabButtonTrailingMargin: CGFloat = 0
|
||||
static let fabButtonBottomMargin: CGFloat = 9
|
||||
}
|
||||
|
||||
/// Remove back bar button title when pushing a view controller.
|
||||
/// This method should be called on the previous controller in UINavigationController stack.
|
||||
@objc func vc_removeBackTitle() {
|
||||
|
@ -61,4 +67,40 @@ extension UIViewController {
|
|||
func vc_removeFromParent() {
|
||||
self.vc_removeChildViewController(viewController: self)
|
||||
}
|
||||
|
||||
/// Adds a floating action button to the bottom-right of the page.
|
||||
/// - Parameters:
|
||||
/// - image: Image to be showed in fab
|
||||
/// - target: target of the button
|
||||
/// - action: action of the button
|
||||
/// - Returns: The FAB view
|
||||
@discardableResult
|
||||
@objc func vc_addFAB(withImage image: UIImage,
|
||||
target: Any?,
|
||||
action: Selector?) -> UIImageView {
|
||||
|
||||
let fabImageView = UIImageView(image: image)
|
||||
fabImageView.translatesAutoresizingMaskIntoConstraints = false
|
||||
fabImageView.backgroundColor = .clear
|
||||
fabImageView.contentMode = .center
|
||||
fabImageView.layer.shadowOpacity = 0.3
|
||||
fabImageView.layer.shadowOffset = CGSize(width: 0, height: 3)
|
||||
fabImageView.isUserInteractionEnabled = true
|
||||
|
||||
self.view.addSubview(fabImageView)
|
||||
|
||||
fabImageView.widthAnchor.constraint(equalToConstant: UIViewControllerConstants.fabButtonSize.width).isActive = true
|
||||
fabImageView.heightAnchor.constraint(equalToConstant: UIViewControllerConstants.fabButtonSize.height).isActive = true
|
||||
fabImageView.trailingAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.trailingAnchor,
|
||||
constant: UIViewControllerConstants.fabButtonTrailingMargin).isActive = true
|
||||
self.view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: fabImageView.bottomAnchor,
|
||||
constant: UIViewControllerConstants.fabButtonBottomMargin).isActive = true
|
||||
|
||||
let tapGestureRecognizer = UITapGestureRecognizer(target: target, action: action)
|
||||
tapGestureRecognizer.numberOfTouchesRequired = 1
|
||||
tapGestureRecognizer.numberOfTapsRequired = 1
|
||||
fabImageView.addGestureRecognizer(tapGestureRecognizer)
|
||||
|
||||
return fabImageView
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,6 +87,7 @@ internal enum Asset {
|
|||
internal static let uploadIcon = ImageAsset(name: "upload_icon")
|
||||
internal static let voiceCallHangonIcon = ImageAsset(name: "voice_call_hangon_icon")
|
||||
internal static let voiceCallHangupIcon = ImageAsset(name: "voice_call_hangup_icon")
|
||||
internal static let addMemberFloatingAction = ImageAsset(name: "add_member_floating_action")
|
||||
internal static let addParticipant = ImageAsset(name: "add_participant")
|
||||
internal static let detailsIcon = ImageAsset(name: "details_icon")
|
||||
internal static let editIcon = ImageAsset(name: "edit_icon")
|
||||
|
|
|
@ -1910,6 +1910,10 @@ internal enum VectorL10n {
|
|||
internal static var leave: String {
|
||||
return VectorL10n.tr("Vector", "leave")
|
||||
}
|
||||
/// Less
|
||||
internal static var less: String {
|
||||
return VectorL10n.tr("Vector", "less")
|
||||
}
|
||||
/// Got it
|
||||
internal static var majorUpdateDoneAction: String {
|
||||
return VectorL10n.tr("Vector", "major_update_done_action")
|
||||
|
|
|
@ -233,7 +233,7 @@ static RageShakeManager* sharedInstance = nil;
|
|||
UIGraphicsEndImageContext();
|
||||
|
||||
// the image is copied in the clipboard
|
||||
[UIPasteboard generalPasteboard].image = image;
|
||||
MXKPasteboardManager.shared.pasteboard.image = image;
|
||||
|
||||
return image;
|
||||
}
|
||||
|
|
|
@ -119,10 +119,6 @@
|
|||
- (void)cancelEditionMode:(BOOL)forceRefresh;
|
||||
|
||||
#pragma mark - Room handling
|
||||
/**
|
||||
Add the (+) button at the right bottom corner of the view.
|
||||
*/
|
||||
- (void)addPlusButton;
|
||||
|
||||
/**
|
||||
Action triggered when the user taps on the (+) button.
|
||||
|
|
|
@ -1606,36 +1606,6 @@
|
|||
|
||||
#pragma mark - Room handling
|
||||
|
||||
- (void)addPlusButton
|
||||
{
|
||||
// Add room options button
|
||||
plusButtonImageView = [[UIImageView alloc] init];
|
||||
[plusButtonImageView setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
[self.view addSubview:plusButtonImageView];
|
||||
|
||||
plusButtonImageView.backgroundColor = [UIColor clearColor];
|
||||
plusButtonImageView.contentMode = UIViewContentModeCenter;
|
||||
plusButtonImageView.image = [UIImage imageNamed:@"plus_floating_action"];
|
||||
plusButtonImageView.layer.shadowOpacity = 0.3;
|
||||
plusButtonImageView.layer.shadowOffset = CGSizeMake(0, 3);
|
||||
|
||||
CGFloat side = 78.0f;
|
||||
[plusButtonImageView.widthAnchor constraintEqualToConstant:side].active = YES;
|
||||
[plusButtonImageView.heightAnchor constraintEqualToConstant:side].active = YES;
|
||||
|
||||
// align to safe area
|
||||
[plusButtonImageView.trailingAnchor constraintEqualToAnchor:self.view.safeAreaLayoutGuide.trailingAnchor].active = YES;
|
||||
[self.view.safeAreaLayoutGuide.bottomAnchor constraintEqualToAnchor:plusButtonImageView.bottomAnchor constant:9].active = YES;
|
||||
|
||||
plusButtonImageView.userInteractionEnabled = YES;
|
||||
|
||||
// Handle tap gesture
|
||||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onPlusButtonPressed)];
|
||||
[tap setNumberOfTouchesRequired:1];
|
||||
[tap setNumberOfTapsRequired:1];
|
||||
[plusButtonImageView addGestureRecognizer:tap];
|
||||
}
|
||||
|
||||
- (void)onPlusButtonPressed
|
||||
{
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
|
|
@ -102,7 +102,9 @@
|
|||
self.groupsSearchBar.placeholder = NSLocalizedStringFromTable(@"search_default_placeholder", @"Vector", nil);
|
||||
|
||||
// @TODO: Add programmatically the (+) button.
|
||||
//[self addPlusButton];
|
||||
// plusButtonImageView = [self vc_addFABWithImage:[UIImage imageNamed:@"plus_floating_action"]
|
||||
// target:self
|
||||
// action:@selector(onPlusButtonPressed)];
|
||||
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
@ -549,63 +551,6 @@
|
|||
|
||||
#pragma mark - Room handling
|
||||
|
||||
- (void)addPlusButton
|
||||
{
|
||||
// Add room options button
|
||||
plusButtonImageView = [[UIImageView alloc] init];
|
||||
[plusButtonImageView setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
[self.view addSubview:plusButtonImageView];
|
||||
|
||||
plusButtonImageView.backgroundColor = [UIColor clearColor];
|
||||
plusButtonImageView.contentMode = UIViewContentModeCenter;
|
||||
plusButtonImageView.image = [UIImage imageNamed:@"plus_floating_action"];
|
||||
plusButtonImageView.layer.shadowOpacity = 0.3;
|
||||
plusButtonImageView.layer.shadowOffset = CGSizeMake(0, 3);
|
||||
|
||||
CGFloat side = 78.0f;
|
||||
NSLayoutConstraint* widthConstraint = [NSLayoutConstraint constraintWithItem:plusButtonImageView
|
||||
attribute:NSLayoutAttributeWidth
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:nil
|
||||
attribute:NSLayoutAttributeNotAnAttribute
|
||||
multiplier:1
|
||||
constant:side];
|
||||
|
||||
NSLayoutConstraint* heightConstraint = [NSLayoutConstraint constraintWithItem:plusButtonImageView
|
||||
attribute:NSLayoutAttributeHeight
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:nil
|
||||
attribute:NSLayoutAttributeNotAnAttribute
|
||||
multiplier:1
|
||||
constant:side];
|
||||
|
||||
NSLayoutConstraint* trailingConstraint = [NSLayoutConstraint constraintWithItem:plusButtonImageView
|
||||
attribute:NSLayoutAttributeTrailing
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.view
|
||||
attribute:NSLayoutAttributeTrailing
|
||||
multiplier:1
|
||||
constant:0];
|
||||
|
||||
NSLayoutConstraint* bottomConstraint = [NSLayoutConstraint constraintWithItem:self.bottomLayoutGuide
|
||||
attribute:NSLayoutAttributeTop
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:plusButtonImageView
|
||||
attribute:NSLayoutAttributeBottom
|
||||
multiplier:1
|
||||
constant:9];
|
||||
|
||||
[NSLayoutConstraint activateConstraints:@[widthConstraint, heightConstraint, trailingConstraint, bottomConstraint]];
|
||||
|
||||
plusButtonImageView.userInteractionEnabled = YES;
|
||||
|
||||
// Handle tap gesture
|
||||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onPlusButtonPressed)];
|
||||
[tap setNumberOfTouchesRequired:1];
|
||||
[tap setNumberOfTapsRequired:1];
|
||||
[plusButtonImageView addGestureRecognizer:tap];
|
||||
}
|
||||
|
||||
- (void)onPlusButtonPressed
|
||||
{
|
||||
__weak typeof(self) weakSelf = self;
|
||||
|
|
|
@ -73,7 +73,9 @@
|
|||
self.recentsTableView.tag = RecentsDataSourceModeHome;
|
||||
|
||||
// Add the (+) button programmatically
|
||||
[self addPlusButton];
|
||||
plusButtonImageView = [self vc_addFABWithImage:[UIImage imageNamed:@"plus_floating_action"]
|
||||
target:self
|
||||
action:@selector(onPlusButtonPressed)];
|
||||
|
||||
// Register table view cell used for rooms collection.
|
||||
[self.recentsTableView registerClass:TableViewCellWithCollectionView.class forCellReuseIdentifier:TableViewCellWithCollectionView.defaultReuseIdentifier];
|
||||
|
|
|
@ -66,10 +66,9 @@
|
|||
self.recentsTableView.tag = RecentsDataSourceModePeople;
|
||||
|
||||
// Add the (+) button programmatically
|
||||
[self addPlusButton];
|
||||
|
||||
// Apply tintColor on the (+) button
|
||||
plusButtonImageView.image = [UIImage imageNamed:@"people_floating_action"];
|
||||
plusButtonImageView = [self vc_addFABWithImage:[UIImage imageNamed:@"people_floating_action"]
|
||||
target:self
|
||||
action:@selector(onPlusButtonPressed)];
|
||||
|
||||
// Register table view cell for contacts.
|
||||
[self.recentsTableView registerClass:ContactTableViewCell.class forCellReuseIdentifier:ContactTableViewCell.defaultReuseIdentifier];
|
||||
|
|
|
@ -51,13 +51,6 @@
|
|||
RoomMemberDetailsViewController *memberDetailsViewController;
|
||||
ContactsTableViewController *contactsPickerViewController;
|
||||
|
||||
// Display a gradient view above the screen.
|
||||
CAGradientLayer* tableViewMaskLayer;
|
||||
|
||||
// Display a button to invite new member.
|
||||
UIImageView* addParticipantButtonImageView;
|
||||
NSLayoutConstraint *addParticipantButtonImageViewBottomConstraint;
|
||||
|
||||
UIAlertController *currentAlert;
|
||||
|
||||
// Observe kThemeServiceDidChangeThemeNotification to handle user interface theme change.
|
||||
|
@ -141,8 +134,12 @@
|
|||
|
||||
[self.tableView registerClass:ContactTableViewCell.class forCellReuseIdentifier:@"ParticipantTableViewCellId"];
|
||||
|
||||
// Add room creation button programmatically
|
||||
[self addAddParticipantButton];
|
||||
|
||||
|
||||
// Add invite members button programmatically
|
||||
[self vc_addFABWithImage:[UIImage imageNamed:@"add_member_floating_action"]
|
||||
target:self
|
||||
action:@selector(onAddParticipantButtonPressed)];
|
||||
|
||||
// Observe user interface theme change.
|
||||
kThemeServiceDidChangeThemeNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:kThemeServiceDidChangeThemeNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notif) {
|
||||
|
@ -168,15 +165,6 @@
|
|||
self.view.backgroundColor = self.tableView.backgroundColor;
|
||||
self.tableView.separatorColor = ThemeService.shared.theme.lineBreakColor;
|
||||
|
||||
// Update the gradient view above the screen
|
||||
CGFloat white = 1.0;
|
||||
[ThemeService.shared.theme.backgroundColor getWhite:&white alpha:nil];
|
||||
CGColorRef opaqueWhiteColor = [UIColor colorWithWhite:white alpha:1.0].CGColor;
|
||||
CGColorRef transparentWhiteColor = [UIColor colorWithWhite:white alpha:0].CGColor;
|
||||
tableViewMaskLayer.colors = @[(__bridge id) transparentWhiteColor, (__bridge id) transparentWhiteColor, (__bridge id) opaqueWhiteColor];
|
||||
|
||||
addParticipantButtonImageView.tintColor = ThemeService.shared.theme.tintColor;
|
||||
|
||||
if (self.tableView.dataSource)
|
||||
{
|
||||
[self.tableView reloadData];
|
||||
|
@ -304,40 +292,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)viewDidLayoutSubviews
|
||||
{
|
||||
[super viewDidLayoutSubviews];
|
||||
|
||||
// Sanity check
|
||||
if (tableViewMaskLayer)
|
||||
{
|
||||
CGRect currentBounds = tableViewMaskLayer.bounds;
|
||||
CGRect newBounds = CGRectIntegral(self.view.frame);
|
||||
|
||||
newBounds.size.height -= self.keyboardHeight;
|
||||
|
||||
// Check if there is an update
|
||||
if (!CGSizeEqualToSize(currentBounds.size, newBounds.size))
|
||||
{
|
||||
newBounds.origin = CGPointZero;
|
||||
|
||||
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseIn
|
||||
animations:^{
|
||||
|
||||
tableViewMaskLayer.bounds = newBounds;
|
||||
|
||||
}
|
||||
completion:^(BOOL finished){
|
||||
}];
|
||||
|
||||
}
|
||||
|
||||
// Hide the addParticipants button on landscape when keyboard is visible
|
||||
BOOL isLandscapeOriented = UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
|
||||
addParticipantButtonImageView.hidden = tableViewMaskLayer.hidden = (isLandscapeOriented && self.keyboardHeight);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)setMxRoom:(MXRoom *)mxRoom
|
||||
|
@ -554,24 +508,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
- (void)setKeyboardHeight:(CGFloat)keyboardHeight
|
||||
{
|
||||
super.keyboardHeight = keyboardHeight;
|
||||
|
||||
// Update addParticipants button position with animation
|
||||
[UIView animateWithDuration:0.3 delay:0 options:UIViewAnimationOptionBeginFromCurrentState | UIViewAnimationOptionCurveEaseIn
|
||||
animations:^{
|
||||
|
||||
addParticipantButtonImageViewBottomConstraint.constant = keyboardHeight + 9;
|
||||
|
||||
// Force to render the view
|
||||
[self.view layoutIfNeeded];
|
||||
|
||||
}
|
||||
completion:^(BOOL finished){
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - Internals
|
||||
|
||||
- (void)refreshTableView
|
||||
|
@ -587,88 +523,6 @@
|
|||
topViewController.navigationItem.leftBarButtonItem = nil;
|
||||
}
|
||||
|
||||
- (void)addAddParticipantButton
|
||||
{
|
||||
// Add blur mask programmatically
|
||||
tableViewMaskLayer = [CAGradientLayer layer];
|
||||
|
||||
// Consider the grayscale components of the ThemeService.shared.theme.backgroundColor.
|
||||
CGFloat white = 1.0;
|
||||
[ThemeService.shared.theme.backgroundColor getWhite:&white alpha:nil];
|
||||
|
||||
CGColorRef opaqueWhiteColor = [UIColor colorWithWhite:white alpha:1.0].CGColor;
|
||||
CGColorRef transparentWhiteColor = [UIColor colorWithWhite:white alpha:0].CGColor;
|
||||
|
||||
tableViewMaskLayer.colors = @[(__bridge id) transparentWhiteColor, (__bridge id) transparentWhiteColor, (__bridge id) opaqueWhiteColor];
|
||||
|
||||
// display a gradient to the rencents bottom (20% of the bottom of the screen)
|
||||
tableViewMaskLayer.locations = @[@0.0F,
|
||||
@0.85F,
|
||||
@1.0F];
|
||||
|
||||
tableViewMaskLayer.bounds = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
|
||||
tableViewMaskLayer.anchorPoint = CGPointZero;
|
||||
|
||||
// CAConstraint is not supported on IOS.
|
||||
// it seems only being supported on Mac OS.
|
||||
// so viewDidLayoutSubviews will refresh the layout bounds.
|
||||
[self.view.layer addSublayer:tableViewMaskLayer];
|
||||
|
||||
// Add + button
|
||||
addParticipantButtonImageView = [[UIImageView alloc] init];
|
||||
[addParticipantButtonImageView setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
[self.view addSubview:addParticipantButtonImageView];
|
||||
|
||||
addParticipantButtonImageView.backgroundColor = [UIColor clearColor];
|
||||
addParticipantButtonImageView.contentMode = UIViewContentModeCenter;
|
||||
addParticipantButtonImageView.image = [UIImage imageNamed:@"add_participant"];
|
||||
|
||||
CGFloat side = 78.0f;
|
||||
NSLayoutConstraint* widthConstraint = [NSLayoutConstraint constraintWithItem:addParticipantButtonImageView
|
||||
attribute:NSLayoutAttributeWidth
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:nil
|
||||
attribute:NSLayoutAttributeNotAnAttribute
|
||||
multiplier:1
|
||||
constant:side];
|
||||
|
||||
NSLayoutConstraint* heightConstraint = [NSLayoutConstraint constraintWithItem:addParticipantButtonImageView
|
||||
attribute:NSLayoutAttributeHeight
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:nil
|
||||
attribute:NSLayoutAttributeNotAnAttribute
|
||||
multiplier:1
|
||||
constant:side];
|
||||
|
||||
NSLayoutConstraint* centerXConstraint = [NSLayoutConstraint constraintWithItem:addParticipantButtonImageView
|
||||
attribute:NSLayoutAttributeCenterX
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:self.view
|
||||
attribute:NSLayoutAttributeCenterX
|
||||
multiplier:1
|
||||
constant:0];
|
||||
|
||||
addParticipantButtonImageViewBottomConstraint = [NSLayoutConstraint constraintWithItem:self.view
|
||||
attribute:NSLayoutAttributeBottom
|
||||
relatedBy:NSLayoutRelationEqual
|
||||
toItem:addParticipantButtonImageView
|
||||
attribute:NSLayoutAttributeBottom
|
||||
multiplier:1
|
||||
constant:self.keyboardHeight + 9];
|
||||
|
||||
// Available on iOS 8 and later
|
||||
[NSLayoutConstraint activateConstraints:@[widthConstraint, heightConstraint, centerXConstraint, addParticipantButtonImageViewBottomConstraint]];
|
||||
|
||||
addParticipantButtonImageView.userInteractionEnabled = YES;
|
||||
|
||||
// Handle tap gesture
|
||||
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(onAddParticipantButtonPressed)];
|
||||
[tap setNumberOfTouchesRequired:1];
|
||||
[tap setNumberOfTapsRequired:1];
|
||||
[tap setDelegate:self];
|
||||
[addParticipantButtonImageView addGestureRecognizer:tap];
|
||||
}
|
||||
|
||||
- (void)onAddParticipantButtonPressed
|
||||
{
|
||||
// Push the contacts picker.
|
||||
|
|
|
@ -50,8 +50,9 @@ final class RoomInfoListViewController: UIViewController {
|
|||
|
||||
private lazy var basicInfoView: RoomInfoBasicView = {
|
||||
let view = RoomInfoBasicView.loadFromNib()
|
||||
view.autoresizingMask = .flexibleWidth
|
||||
view.translatesAutoresizingMaskIntoConstraints = true
|
||||
view.onTopicSizeChange = { _ in
|
||||
self.view.setNeedsLayout()
|
||||
}
|
||||
return view
|
||||
}()
|
||||
|
||||
|
@ -127,25 +128,25 @@ final class RoomInfoListViewController: UIViewController {
|
|||
return self.theme.statusBarStyle
|
||||
}
|
||||
|
||||
override func viewDidLayoutSubviews() {
|
||||
super.viewDidLayoutSubviews()
|
||||
|
||||
mainTableView.vc_relayoutHeaderView()
|
||||
}
|
||||
|
||||
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
|
||||
coordinator.animate(alongsideTransition: {_ in
|
||||
self.basicInfoView.updateTrimmingOnTopic()
|
||||
}, completion: nil)
|
||||
}
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func updateSections(with viewData: RoomInfoListViewData) {
|
||||
isRoomDirect = viewData.isDirect
|
||||
basicInfoView.configure(withViewData: viewData.basicInfoViewData)
|
||||
|
||||
var tmpSections: [Section] = []
|
||||
|
||||
if viewData.isEncrypted {
|
||||
let footer = viewData.isDirect ?
|
||||
VectorL10n.roomParticipantsSecurityInformationRoomEncryptedForDm :
|
||||
VectorL10n.roomParticipantsSecurityInformationRoomEncrypted
|
||||
let sectionSecurity = Section(header: VectorL10n.securitySettingsTitle,
|
||||
rows: [],
|
||||
footer: footer)
|
||||
|
||||
tmpSections.append(sectionSecurity)
|
||||
}
|
||||
|
||||
let rowSettings = Row(type: .default, icon: Asset.Images.settingsIcon.image, text: VectorL10n.roomDetailsSettings, accessoryType: .disclosureIndicator) {
|
||||
self.viewModel.process(viewAction: .navigate(target: .settings))
|
||||
}
|
||||
|
@ -163,7 +164,7 @@ final class RoomInfoListViewController: UIViewController {
|
|||
rowUploads],
|
||||
footer: nil)
|
||||
|
||||
let leaveTitle = viewData.isDirect ?
|
||||
let leaveTitle = viewData.basicInfoViewData.isDirect ?
|
||||
VectorL10n.roomParticipantsLeavePromptTitleForDm :
|
||||
VectorL10n.roomParticipantsLeavePromptTitle
|
||||
let rowLeave = Row(type: .destructive, icon: Asset.Images.roomActionLeave.image, text: leaveTitle, accessoryType: .none) {
|
||||
|
|
|
@ -21,7 +21,5 @@ import Foundation
|
|||
/// View data object to represent view
|
||||
struct RoomInfoListViewData {
|
||||
let numberOfMembers: Int
|
||||
let isEncrypted: Bool
|
||||
let isDirect: Bool
|
||||
let basicInfoViewData: RoomInfoBasicViewData
|
||||
}
|
||||
|
|
|
@ -41,11 +41,11 @@ final class RoomInfoListViewModel: NSObject, RoomInfoListViewModelType {
|
|||
roomDisplayName: room.summary.displayname,
|
||||
mainRoomAlias: room.summary.aliases?.first,
|
||||
roomTopic: room.summary.topic,
|
||||
encryptionImage: encryptionImage)
|
||||
encryptionImage: encryptionImage,
|
||||
isEncrypted: room.summary.isEncrypted,
|
||||
isDirect: room.isDirect)
|
||||
|
||||
return RoomInfoListViewData(numberOfMembers: Int(room.summary.membersCount.joined),
|
||||
isEncrypted: room.summary.isEncrypted,
|
||||
isDirect: room.isDirect,
|
||||
basicInfoViewData: basicInfoViewData)
|
||||
}
|
||||
|
||||
|
|
|
@ -16,8 +16,15 @@
|
|||
|
||||
import UIKit
|
||||
import Reusable
|
||||
import ReadMoreTextView
|
||||
|
||||
class RoomInfoBasicView: UIView {
|
||||
|
||||
private enum TopicTextViewConstants {
|
||||
static let font = UIFont.systemFont(ofSize: 15)
|
||||
static let defaultNumberOfLines = 4
|
||||
static let moreLessTextPadding = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
|
||||
}
|
||||
|
||||
@IBOutlet private weak var mainStackView: UIStackView!
|
||||
@IBOutlet private weak var avatarImageView: MXKImageView!
|
||||
|
@ -39,7 +46,42 @@ class RoomInfoBasicView: UIView {
|
|||
@IBOutlet private weak var badgeImageView: UIImageView!
|
||||
@IBOutlet private weak var roomNameLabel: UILabel!
|
||||
@IBOutlet private weak var roomAddressLabel: UILabel!
|
||||
@IBOutlet private weak var roomTopicLabel: UILabel!
|
||||
@IBOutlet private weak var topicContainerView: UIView!
|
||||
@IBOutlet private weak var topicTitleLabel: UILabel! {
|
||||
didSet {
|
||||
topicTitleLabel.text = VectorL10n.roomDetailsTopic
|
||||
}
|
||||
}
|
||||
@IBOutlet private weak var roomTopicTextView: ReadMoreTextView! {
|
||||
didSet {
|
||||
roomTopicTextView.contentInset = .zero
|
||||
roomTopicTextView.textContainerInset = .zero
|
||||
roomTopicTextView.textContainer.lineFragmentPadding = 0
|
||||
roomTopicTextView.readMoreTextPadding = TopicTextViewConstants.moreLessTextPadding
|
||||
roomTopicTextView.readLessTextPadding = TopicTextViewConstants.moreLessTextPadding
|
||||
roomTopicTextView.shouldTrim = true
|
||||
roomTopicTextView.maximumNumberOfLines = TopicTextViewConstants.defaultNumberOfLines
|
||||
roomTopicTextView.onSizeChange = { _ in
|
||||
self.roomTopicTextView.textAlignment = .left
|
||||
self.onTopicSizeChange?(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
@IBOutlet private weak var securityContainerView: UIView!
|
||||
@IBOutlet private weak var securityTitleLabel: UILabel!
|
||||
@IBOutlet private weak var securityInformationLabel: UILabel!
|
||||
|
||||
/// Block to be invoked when topic text view changes its content size.
|
||||
var onTopicSizeChange: ((RoomInfoBasicView) -> Void)?
|
||||
|
||||
/// Force to update topic text view trimming.
|
||||
func updateTrimmingOnTopic() {
|
||||
roomTopicTextView.setNeedsUpdateTrim()
|
||||
let currentValue = roomTopicTextView.shouldTrim
|
||||
roomTopicTextView.shouldTrim = !currentValue
|
||||
roomTopicTextView.shouldTrim = currentValue
|
||||
roomTopicTextView.textAlignment = .left
|
||||
}
|
||||
|
||||
func configure(withViewData viewData: RoomInfoBasicViewData) {
|
||||
let avatarImage = AvatarGenerator.generateAvatar(forMatrixItem: viewData.roomId, withDisplayName: viewData.roomDisplayName)
|
||||
|
@ -61,10 +103,15 @@ class RoomInfoBasicView: UIView {
|
|||
roomNameLabel.text = viewData.roomDisplayName
|
||||
roomAddressLabel.text = viewData.mainRoomAlias
|
||||
roomAddressLabel.isHidden = roomAddressLabel.text?.isEmpty ?? true
|
||||
roomTopicLabel.text = viewData.roomTopic
|
||||
roomTopicLabel.isHidden = roomTopicLabel.text?.isEmpty ?? true
|
||||
roomTopicTextView.text = viewData.roomTopic
|
||||
topicContainerView.isHidden = roomTopicTextView.text?.isEmpty ?? true
|
||||
securityTitleLabel.text = VectorL10n.securitySettingsTitle
|
||||
securityInformationLabel.text = viewData.isDirect ?
|
||||
VectorL10n.roomParticipantsSecurityInformationRoomEncryptedForDm :
|
||||
VectorL10n.roomParticipantsSecurityInformationRoomEncrypted
|
||||
securityContainerView.isHidden = !viewData.isEncrypted
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
extension RoomInfoBasicView: NibLoadable {}
|
||||
|
@ -75,7 +122,33 @@ extension RoomInfoBasicView: Themable {
|
|||
backgroundColor = theme.headerBackgroundColor
|
||||
roomNameLabel.textColor = theme.textPrimaryColor
|
||||
roomAddressLabel.textColor = theme.textSecondaryColor
|
||||
roomTopicLabel.textColor = theme.textSecondaryColor
|
||||
topicTitleLabel.textColor = theme.textSecondaryColor
|
||||
roomTopicTextView.textColor = theme.textPrimaryColor
|
||||
roomTopicTextView.linkTextAttributes = [
|
||||
NSAttributedString.Key.font: TopicTextViewConstants.font,
|
||||
NSAttributedString.Key.foregroundColor: theme.tintColor
|
||||
]
|
||||
let mutableReadMore = NSMutableAttributedString(string: "… ", attributes: [
|
||||
NSAttributedString.Key.font: TopicTextViewConstants.font,
|
||||
NSAttributedString.Key.foregroundColor: theme.textPrimaryColor
|
||||
])
|
||||
let attributedMore = NSAttributedString(string: VectorL10n.more, attributes: [
|
||||
NSAttributedString.Key.font: TopicTextViewConstants.font,
|
||||
NSAttributedString.Key.foregroundColor: theme.tintColor
|
||||
])
|
||||
mutableReadMore.append(attributedMore)
|
||||
roomTopicTextView.attributedReadMoreText = mutableReadMore
|
||||
|
||||
let mutableReadLess = NSMutableAttributedString(string: " ")
|
||||
let attributedLess = NSAttributedString(string: VectorL10n.less, attributes: [
|
||||
NSAttributedString.Key.font: TopicTextViewConstants.font,
|
||||
NSAttributedString.Key.foregroundColor: theme.tintColor
|
||||
])
|
||||
mutableReadLess.append(attributedLess)
|
||||
roomTopicTextView.attributedReadLessText = mutableReadLess
|
||||
|
||||
securityTitleLabel.textColor = theme.textSecondaryColor
|
||||
securityInformationLabel.textColor = theme.textPrimaryColor
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,21 +10,21 @@
|
|||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="iN0-l3-epB" customClass="RoomInfoBasicView" customModule="Riot" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="183"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="307"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" widthSizable="YES" flexibleMaxX="YES" flexibleMinY="YES" heightSizable="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" verticalCompressionResistancePriority="751" axis="vertical" distribution="equalSpacing" alignment="center" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="xmU-kN-zva">
|
||||
<rect key="frame" x="0.0" y="0.0" width="414" height="183"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" verticalCompressionResistancePriority="751" axis="vertical" alignment="center" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="xmU-kN-zva">
|
||||
<rect key="frame" x="26" y="0.0" width="362" height="307"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Tgy-Pv-0Gz">
|
||||
<rect key="frame" x="87" y="0.0" width="240" height="1"/>
|
||||
<rect key="frame" x="61" y="0.0" width="240" height="1"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="1" id="5Hy-Jn-UrY"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="uhx-GK-2je">
|
||||
<rect key="frame" x="167" y="11" width="80" height="80"/>
|
||||
<rect key="frame" x="141" y="9" width="80" height="80"/>
|
||||
<subviews>
|
||||
<view clipsSubviews="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="6tV-Ha-dWM" customClass="MXKImageView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="80" height="80"/>
|
||||
|
@ -63,34 +63,94 @@
|
|||
<constraint firstAttribute="trailing" secondItem="szu-r5-TIX" secondAttribute="trailing" id="xqQ-Ue-Ldl"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Label" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ekk-PI-fnh">
|
||||
<rect key="frame" x="182" y="100.5" width="50.5" height="24"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Label" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ekk-PI-fnh">
|
||||
<rect key="frame" x="156" y="97" width="50.5" height="24"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="20"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Label" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Yjw-ez-u4W">
|
||||
<rect key="frame" x="187.5" y="134.5" width="39.5" height="19.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Label" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Qyh-eC-KBG">
|
||||
<rect key="frame" x="187.5" y="163.5" width="39.5" height="19.5"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Yjw-ez-u4W">
|
||||
<rect key="frame" x="161.5" y="129" width="39.5" height="19.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="16"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="NSk-JY-5iY">
|
||||
<rect key="frame" x="0.0" y="156.5" width="362" height="78"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="Topic" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cTV-D7-Uha">
|
||||
<rect key="frame" x="0.0" y="8" width="33" height="16"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" verticalHuggingPriority="252" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" text="Lorem ipsum" translatesAutoresizingMaskIntoConstraints="NO" id="DCx-MH-TSC" customClass="ReadMoreTextView" customModule="ReadMoreTextView">
|
||||
<rect key="frame" x="0.0" y="36" width="362" height="34"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<color key="textColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
|
||||
<dataDetectorType key="dataDetectorTypes" phoneNumber="YES" link="YES" address="YES" calendarEvent="YES" shipmentTrackingNumber="YES" flightNumber="YES"/>
|
||||
<userDefinedRuntimeAttributes>
|
||||
<userDefinedRuntimeAttribute type="number" keyPath="maximumNumberOfLines">
|
||||
<integer key="value" value="4"/>
|
||||
</userDefinedRuntimeAttribute>
|
||||
<userDefinedRuntimeAttribute type="boolean" keyPath="shouldTrim" value="YES"/>
|
||||
</userDefinedRuntimeAttributes>
|
||||
</textView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="DCx-MH-TSC" firstAttribute="top" secondItem="cTV-D7-Uha" secondAttribute="bottom" constant="12" id="LY8-cQ-p3H"/>
|
||||
<constraint firstAttribute="trailing" secondItem="DCx-MH-TSC" secondAttribute="trailing" id="Nrg-wG-AlG"/>
|
||||
<constraint firstItem="cTV-D7-Uha" firstAttribute="leading" secondItem="NSk-JY-5iY" secondAttribute="leading" id="Uab-wX-GVB"/>
|
||||
<constraint firstItem="cTV-D7-Uha" firstAttribute="top" secondItem="NSk-JY-5iY" secondAttribute="top" constant="8" id="Ut8-xr-JTf"/>
|
||||
<constraint firstItem="DCx-MH-TSC" firstAttribute="leading" secondItem="NSk-JY-5iY" secondAttribute="leading" id="c6P-hF-axm"/>
|
||||
<constraint firstAttribute="bottom" secondItem="DCx-MH-TSC" secondAttribute="bottom" constant="8" id="h2M-48-9Ly"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="l54-5L-xAv">
|
||||
<rect key="frame" x="0.0" y="242.5" width="362" height="64.5"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="Security" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="peB-51-q5w">
|
||||
<rect key="frame" x="0.0" y="8" width="50" height="18.5"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="13"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" verticalHuggingPriority="251" text="Messages in this room are end to end encrypted" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="HAS-Tr-iTE">
|
||||
<rect key="frame" x="0.0" y="38.5" width="362" height="18"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="HAS-Tr-iTE" secondAttribute="trailing" id="6Ai-05-Ysx"/>
|
||||
<constraint firstItem="HAS-Tr-iTE" firstAttribute="top" secondItem="peB-51-q5w" secondAttribute="bottom" constant="12" id="HZu-IN-h4I"/>
|
||||
<constraint firstItem="peB-51-q5w" firstAttribute="leading" secondItem="l54-5L-xAv" secondAttribute="leading" id="IjP-wz-F8H"/>
|
||||
<constraint firstItem="peB-51-q5w" firstAttribute="top" secondItem="l54-5L-xAv" secondAttribute="top" constant="8" id="LFK-W4-Gpw"/>
|
||||
<constraint firstAttribute="bottom" secondItem="HAS-Tr-iTE" secondAttribute="bottom" constant="8" id="Sjx-QS-Rfb"/>
|
||||
<constraint firstItem="HAS-Tr-iTE" firstAttribute="leading" secondItem="l54-5L-xAv" secondAttribute="leading" id="vnf-AI-9s6"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="NSk-JY-5iY" firstAttribute="leading" secondItem="xmU-kN-zva" secondAttribute="leading" id="Rds-uI-ZDv"/>
|
||||
<constraint firstAttribute="trailing" secondItem="l54-5L-xAv" secondAttribute="trailing" id="ggk-iS-EdG"/>
|
||||
<constraint firstAttribute="trailing" secondItem="NSk-JY-5iY" secondAttribute="trailing" id="lwP-Fm-6fy"/>
|
||||
<constraint firstItem="l54-5L-xAv" firstAttribute="leading" secondItem="xmU-kN-zva" secondAttribute="leading" id="q9M-lt-GmG"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="xmU-kN-zva" secondAttribute="trailing" id="JAT-xr-qng"/>
|
||||
<constraint firstAttribute="trailingMargin" secondItem="xmU-kN-zva" secondAttribute="trailing" constant="6" id="JAT-xr-qng"/>
|
||||
<constraint firstAttribute="bottom" secondItem="xmU-kN-zva" secondAttribute="bottom" id="Zen-46-8Ks"/>
|
||||
<constraint firstItem="xmU-kN-zva" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="ciH-WD-B1a"/>
|
||||
<constraint firstItem="xmU-kN-zva" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="qbE-Xx-IK9"/>
|
||||
<constraint firstItem="xmU-kN-zva" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leadingMargin" constant="6" id="qbE-Xx-IK9"/>
|
||||
</constraints>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
|
@ -99,10 +159,15 @@
|
|||
<outlet property="mainStackView" destination="xmU-kN-zva" id="Hsg-6X-ATq"/>
|
||||
<outlet property="roomAddressLabel" destination="Yjw-ez-u4W" id="R1L-VC-qHV"/>
|
||||
<outlet property="roomNameLabel" destination="ekk-PI-fnh" id="prM-OG-suY"/>
|
||||
<outlet property="roomTopicLabel" destination="Qyh-eC-KBG" id="qN7-ic-y6n"/>
|
||||
<outlet property="roomTopicTextView" destination="DCx-MH-TSC" id="MB0-cS-wfD"/>
|
||||
<outlet property="securityContainerView" destination="l54-5L-xAv" id="Duy-QA-wrD"/>
|
||||
<outlet property="securityInformationLabel" destination="HAS-Tr-iTE" id="GZC-gT-q2z"/>
|
||||
<outlet property="securityTitleLabel" destination="peB-51-q5w" id="hbl-K6-AbE"/>
|
||||
<outlet property="shadowView" destination="szu-r5-TIX" id="LDd-uy-FAG"/>
|
||||
<outlet property="topicContainerView" destination="NSk-JY-5iY" id="YCo-cp-dbU"/>
|
||||
<outlet property="topicTitleLabel" destination="cTV-D7-Uha" id="nt9-MZ-4t7"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="243.47826086956525" y="-273.54910714285711"/>
|
||||
<point key="canvasLocation" x="155.07246376811597" y="-254.12946428571428"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
|
|
|
@ -26,4 +26,6 @@ struct RoomInfoBasicViewData {
|
|||
let mainRoomAlias: String?
|
||||
let roomTopic: String?
|
||||
let encryptionImage: UIImage?
|
||||
let isEncrypted: Bool
|
||||
let isDirect: Bool
|
||||
}
|
||||
|
|
|
@ -2622,7 +2622,7 @@
|
|||
|
||||
if (permalink)
|
||||
{
|
||||
[[UIPasteboard generalPasteboard] setString:permalink];
|
||||
MXKPasteboardManager.shared.pasteboard.string = permalink;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -5256,7 +5256,7 @@
|
|||
|
||||
if (textMessage)
|
||||
{
|
||||
[UIPasteboard generalPasteboard].string = textMessage;
|
||||
MXKPasteboardManager.shared.pasteboard.string = textMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -898,7 +898,7 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
|
|||
|
||||
if (roomdId)
|
||||
{
|
||||
[[UIPasteboard generalPasteboard] setString:roomdId];
|
||||
MXKPasteboardManager.shared.pasteboard.string = roomdId;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1006,7 +1006,7 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
|
|||
|
||||
if (roomAlias)
|
||||
{
|
||||
[[UIPasteboard generalPasteboard] setString:roomAlias];
|
||||
MXKPasteboardManager.shared.pasteboard.string = roomAlias;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1031,7 +1031,7 @@ NSString *const kRoomSettingsAdvancedE2eEnabledCellViewIdentifier = @"kRoomSetti
|
|||
|
||||
if (permalink)
|
||||
{
|
||||
[[UIPasteboard generalPasteboard] setString:permalink];
|
||||
MXKPasteboardManager.shared.pasteboard.string = permalink;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -55,9 +55,9 @@
|
|||
self.recentsTableView.tag = RecentsDataSourceModeRooms;
|
||||
|
||||
// Add the (+) button programmatically
|
||||
[self addPlusButton];
|
||||
|
||||
plusButtonImageView.image = [UIImage imageNamed:@"rooms_floating_action"];
|
||||
plusButtonImageView = [self vc_addFABWithImage:[UIImage imageNamed:@"rooms_floating_action"]
|
||||
target:self
|
||||
action:@selector(onPlusButtonPressed)];
|
||||
|
||||
self.enableStickyHeaders = YES;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="V8j-Lb-PgC">
|
||||
<device id="retina5_9" orientation="portrait" appearance="light"/>
|
||||
<device id="retina4_7" orientation="portrait" appearance="light"/>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
|
||||
|
@ -13,14 +13,14 @@
|
|||
<objects>
|
||||
<viewController extendedLayoutIncludesOpaqueBars="YES" automaticallyAdjustsScrollViewInsets="NO" id="V8j-Lb-PgC" customClass="EnterPinCodeViewController" customModule="Riot" customModuleProvider="target" sceneMemberID="viewController">
|
||||
<view key="view" contentMode="scaleToFill" id="EL9-GA-lwo">
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="812"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<view hidden="YES" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="1YE-D1-eHn">
|
||||
<rect key="frame" x="0.0" y="64" width="375" height="694"/>
|
||||
<rect key="frame" x="0.0" y="20" width="375" height="627"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="app_symbol" translatesAutoresizingMaskIntoConstraints="NO" id="8qz-Yk-9a4">
|
||||
<rect key="frame" x="137.66666666666666" y="277" width="100" height="100"/>
|
||||
<rect key="frame" x="137.5" y="243.5" width="100" height="100"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="100" id="Ux9-pH-SW9"/>
|
||||
<constraint firstAttribute="height" constant="100" id="o3K-YH-5tn"/>
|
||||
|
@ -33,52 +33,34 @@
|
|||
<constraint firstItem="8qz-Yk-9a4" firstAttribute="centerX" secondItem="1YE-D1-eHn" secondAttribute="centerX" id="cPb-3H-3yK"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="DMT-DS-IA8">
|
||||
<rect key="frame" x="0.0" y="52" width="375" height="718"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" alignment="center" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="DMT-DS-IA8">
|
||||
<rect key="frame" x="0.0" y="8" width="375" height="651"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="ztg-5t-ECh" userLabel="Container">
|
||||
<rect key="frame" x="20" y="0.0" width="335" height="172.33333333333334"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="app_symbol" translatesAutoresizingMaskIntoConstraints="NO" id="UHg-qE-anw">
|
||||
<rect key="frame" x="147.66666666666666" y="8" width="40" height="40"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="40" id="ERR-Np-6I1"/>
|
||||
<constraint firstAttribute="height" constant="40" id="zYD-Rk-nOH"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Choose a PIN for security" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bxI-mu-qng">
|
||||
<rect key="frame" x="0.0" y="57.000000000000007" width="335" height="26.333333333333336"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="22"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="PINs help keep your profile, messages and contacts secure, so only you can access them." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Rn2-qe-htS">
|
||||
<rect key="frame" x="0.0" y="111.33333333333334" width="335" height="61"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" image="app_symbol" translatesAutoresizingMaskIntoConstraints="NO" id="UHg-qE-anw">
|
||||
<rect key="frame" x="167.5" y="0.0" width="40" height="40"/>
|
||||
<constraints>
|
||||
<constraint firstItem="Rn2-qe-htS" firstAttribute="centerX" secondItem="ztg-5t-ECh" secondAttribute="centerX" id="18L-xF-ADZ"/>
|
||||
<constraint firstItem="Rn2-qe-htS" firstAttribute="top" secondItem="bxI-mu-qng" secondAttribute="bottom" constant="28" id="HtF-cu-6el"/>
|
||||
<constraint firstItem="bxI-mu-qng" firstAttribute="leading" secondItem="ztg-5t-ECh" secondAttribute="leading" id="IMC-TT-zWD"/>
|
||||
<constraint firstAttribute="bottom" secondItem="Rn2-qe-htS" secondAttribute="bottom" id="IW3-jM-53d"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Rn2-qe-htS" secondAttribute="trailing" id="Jda-DD-urk"/>
|
||||
<constraint firstItem="UHg-qE-anw" firstAttribute="centerX" secondItem="ztg-5t-ECh" secondAttribute="centerX" id="Vhm-GS-xYs"/>
|
||||
<constraint firstAttribute="trailing" secondItem="bxI-mu-qng" secondAttribute="trailing" id="Vug-jC-5c4"/>
|
||||
<constraint firstItem="Rn2-qe-htS" firstAttribute="leading" secondItem="ztg-5t-ECh" secondAttribute="leading" id="kWf-33-mfM"/>
|
||||
<constraint firstItem="bxI-mu-qng" firstAttribute="top" secondItem="UHg-qE-anw" secondAttribute="bottom" constant="9" id="laj-kY-eW1"/>
|
||||
<constraint firstItem="bxI-mu-qng" firstAttribute="centerX" secondItem="ztg-5t-ECh" secondAttribute="centerX" id="p4o-hz-jZJ"/>
|
||||
<constraint firstItem="UHg-qE-anw" firstAttribute="top" secondItem="ztg-5t-ECh" secondAttribute="top" constant="8" id="uj5-KC-7FD"/>
|
||||
<constraint firstAttribute="height" constant="40" id="5If-kl-LuA"/>
|
||||
<constraint firstAttribute="width" constant="40" id="EK6-ed-26b"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="equalSpacing" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="l5x-qO-sdf">
|
||||
<rect key="frame" x="2" y="211" width="371" height="78.666666666666686"/>
|
||||
</imageView>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" text="Welcome back.Choose a PIN for security" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="bxI-mu-qng">
|
||||
<rect key="frame" x="16" y="59" width="343" height="53"/>
|
||||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="22"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Rn2-qe-htS">
|
||||
<rect key="frame" x="16" y="131.5" width="343" height="54"/>
|
||||
<string key="text">Setting up a PIN lets you protect data like messages and contacts, so only you can access them by entering the PIN at the start of the app.</string>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="15"/>
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="l5x-qO-sdf">
|
||||
<rect key="frame" x="2" y="204.5" width="371" height="79"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="24" translatesAutoresizingMaskIntoConstraints="NO" id="xi9-P9-8WP">
|
||||
<rect key="frame" x="101.66666666666669" y="0.0" width="168" height="24"/>
|
||||
<rect key="frame" x="101.5" y="0.0" width="168" height="24"/>
|
||||
<subviews>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="selection_untick" translatesAutoresizingMaskIntoConstraints="NO" id="Gwx-8X-ZWk">
|
||||
<rect key="frame" x="0.0" y="0.0" width="24" height="24"/>
|
||||
|
@ -88,14 +70,14 @@
|
|||
</constraints>
|
||||
</imageView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="1" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="selection_untick" translatesAutoresizingMaskIntoConstraints="NO" id="qDY-R1-l5l">
|
||||
<rect key="frame" x="47.999999999999986" y="0.0" width="24" height="24"/>
|
||||
<rect key="frame" x="48" y="0.0" width="24" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="24" id="QDg-LP-R4J"/>
|
||||
<constraint firstAttribute="height" constant="24" id="f4G-d8-hoA"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<imageView clipsSubviews="YES" userInteractionEnabled="NO" tag="2" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="selection_untick" translatesAutoresizingMaskIntoConstraints="NO" id="X0l-q3-fXm">
|
||||
<rect key="frame" x="95.999999999999986" y="0.0" width="24" height="24"/>
|
||||
<rect key="frame" x="96" y="0.0" width="24" height="24"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="24" id="HQA-9R-8bC"/>
|
||||
<constraint firstAttribute="height" constant="24" id="Zjd-RW-DiW"/>
|
||||
|
@ -111,7 +93,7 @@
|
|||
</subviews>
|
||||
</stackView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="CBc-7Z-a5Z">
|
||||
<rect key="frame" x="0.0" y="23.999999999999996" width="371" height="54.666666666666657"/>
|
||||
<rect key="frame" x="0.0" y="24" width="371" height="55"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Q0w-RD-JD3">
|
||||
<rect key="frame" x="0.0" y="8" width="371" height="2"/>
|
||||
|
@ -121,7 +103,7 @@
|
|||
</constraints>
|
||||
</view>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="For security reasons, this PIN isn't available. Please try another PIN" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="H5g-FI-xEj">
|
||||
<rect key="frame" x="8" y="18" width="355" height="28.666666666666671"/>
|
||||
<rect key="frame" x="8" y="18" width="355" height="29"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<color key="textColor" systemColor="systemRedColor" red="1" green="0.23137254900000001" blue="0.18823529410000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
|
@ -141,11 +123,11 @@
|
|||
</view>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" alignment="center" spacing="21" translatesAutoresizingMaskIntoConstraints="NO" id="W0M-eq-abZ">
|
||||
<rect key="frame" x="65.666666666666686" y="328.33333333333331" width="244" height="302.99999999999994"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" distribution="fillEqually" alignment="center" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="W0M-eq-abZ">
|
||||
<rect key="frame" x="77.5" y="302.5" width="220" height="276"/>
|
||||
<subviews>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="32" translatesAutoresizingMaskIntoConstraints="NO" id="Uqh-o2-7HP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="244" height="60"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="Uqh-o2-7HP">
|
||||
<rect key="frame" x="0.0" y="0.0" width="220" height="60"/>
|
||||
<subviews>
|
||||
<button opaque="NO" tag="1" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="BEe-II-qt8">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
|
||||
|
@ -160,7 +142,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" tag="2" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="vRL-nn-bIH">
|
||||
<rect key="frame" x="91.999999999999986" y="0.0" width="60.000000000000014" height="60"/>
|
||||
<rect key="frame" x="80" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="60" id="HaJ-0E-bl3"/>
|
||||
<constraint firstAttribute="width" constant="60" id="JJz-zL-t77"/>
|
||||
|
@ -172,7 +154,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" tag="3" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="m5E-4b-a2B">
|
||||
<rect key="frame" x="184" y="0.0" width="60" height="60"/>
|
||||
<rect key="frame" x="160" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="60" id="9Uy-xG-5Vq"/>
|
||||
<constraint firstAttribute="width" constant="60" id="EZw-k5-DP8"/>
|
||||
|
@ -185,8 +167,8 @@
|
|||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="32" translatesAutoresizingMaskIntoConstraints="NO" id="Z9D-6N-neq">
|
||||
<rect key="frame" x="0.0" y="81" width="244" height="60"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="Z9D-6N-neq">
|
||||
<rect key="frame" x="0.0" y="72" width="220" height="60"/>
|
||||
<subviews>
|
||||
<button opaque="NO" tag="4" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Q2U-ek-vSc">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
|
||||
|
@ -201,7 +183,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" tag="5" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ziv-SY-nXQ">
|
||||
<rect key="frame" x="91.999999999999986" y="0.0" width="60.000000000000014" height="60"/>
|
||||
<rect key="frame" x="80" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="60" id="5Ry-eq-V0D"/>
|
||||
<constraint firstAttribute="height" constant="60" id="iCm-G8-2Us"/>
|
||||
|
@ -213,7 +195,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" tag="6" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="PNU-iI-oCX">
|
||||
<rect key="frame" x="184" y="0.0" width="60" height="60"/>
|
||||
<rect key="frame" x="160" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="60" id="odD-FC-4eB"/>
|
||||
<constraint firstAttribute="height" constant="60" id="zHt-bd-Jwg"/>
|
||||
|
@ -226,8 +208,8 @@
|
|||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="32" translatesAutoresizingMaskIntoConstraints="NO" id="YeU-UN-Uo0">
|
||||
<rect key="frame" x="0.0" y="162.00000000000006" width="244" height="60"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="YeU-UN-Uo0">
|
||||
<rect key="frame" x="0.0" y="144" width="220" height="60"/>
|
||||
<subviews>
|
||||
<button opaque="NO" tag="7" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Lnz-5u-oFb">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
|
||||
|
@ -242,7 +224,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" tag="8" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="OCE-R0-CMN">
|
||||
<rect key="frame" x="91.999999999999986" y="0.0" width="60.000000000000014" height="60"/>
|
||||
<rect key="frame" x="80" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="60" id="5LE-yh-yoi"/>
|
||||
<constraint firstAttribute="height" constant="60" id="65e-mr-hid"/>
|
||||
|
@ -254,7 +236,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" tag="9" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1dz-Qd-zCl">
|
||||
<rect key="frame" x="184" y="0.0" width="60" height="60"/>
|
||||
<rect key="frame" x="160" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="60" id="rS1-XX-Xw9"/>
|
||||
<constraint firstAttribute="height" constant="60" id="zza-iD-Oue"/>
|
||||
|
@ -267,8 +249,8 @@
|
|||
</button>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="32" translatesAutoresizingMaskIntoConstraints="NO" id="Nrp-tS-u1k">
|
||||
<rect key="frame" x="0.0" y="243.00000000000006" width="244" height="60"/>
|
||||
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="Nrp-tS-u1k">
|
||||
<rect key="frame" x="0.0" y="216" width="220" height="60"/>
|
||||
<subviews>
|
||||
<button opaque="NO" userInteractionEnabled="NO" tag="-99" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DEv-rc-fGB">
|
||||
<rect key="frame" x="0.0" y="0.0" width="60" height="60"/>
|
||||
|
@ -279,7 +261,7 @@
|
|||
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="28"/>
|
||||
</button>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="sc1-u3-yvh">
|
||||
<rect key="frame" x="91.999999999999986" y="0.0" width="60.000000000000014" height="60"/>
|
||||
<rect key="frame" x="80" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="60" id="DDy-yf-FOR"/>
|
||||
<constraint firstAttribute="width" constant="60" id="vSL-tm-biX"/>
|
||||
|
@ -291,7 +273,7 @@
|
|||
</connections>
|
||||
</button>
|
||||
<button opaque="NO" tag="-1" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="LpO-9j-dlN">
|
||||
<rect key="frame" x="184" y="0.0" width="60" height="60"/>
|
||||
<rect key="frame" x="160" y="0.0" width="60" height="60"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="60" id="DAY-CR-kKO"/>
|
||||
<constraint firstAttribute="height" constant="60" id="iDt-BW-fEz"/>
|
||||
|
@ -306,31 +288,27 @@
|
|||
</stackView>
|
||||
</subviews>
|
||||
</stackView>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="nCW-ER-9SF" userLabel="Container">
|
||||
<rect key="frame" x="67.666666666666686" y="670" width="240" height="48"/>
|
||||
<subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CRt-Fb-0Dq">
|
||||
<rect key="frame" x="0.0" y="0.0" width="240" height="48"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<state key="normal" title="Forgot PIN"/>
|
||||
<connections>
|
||||
<action selector="forgotPinButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="hE4-CJ-Bdh"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="CRt-Fb-0Dq">
|
||||
<rect key="frame" x="146.5" y="598" width="82" height="33"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<state key="normal" title="Forgot PIN"/>
|
||||
<connections>
|
||||
<action selector="forgotPinButtonAction:" destination="V8j-Lb-PgC" eventType="touchUpInside" id="hE4-CJ-Bdh"/>
|
||||
</connections>
|
||||
</button>
|
||||
<view userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="N9V-f7-d5k">
|
||||
<rect key="frame" x="67.5" y="650" width="240" height="1"/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
||||
<constraints>
|
||||
<constraint firstItem="CRt-Fb-0Dq" firstAttribute="top" secondItem="nCW-ER-9SF" secondAttribute="top" id="QVD-G0-uHm"/>
|
||||
<constraint firstAttribute="bottom" secondItem="CRt-Fb-0Dq" secondAttribute="bottom" id="gJw-QQ-7PO"/>
|
||||
<constraint firstAttribute="trailing" secondItem="CRt-Fb-0Dq" secondAttribute="trailing" id="gnV-kg-BCW"/>
|
||||
<constraint firstAttribute="height" constant="48" id="whx-HV-FXN"/>
|
||||
<constraint firstItem="CRt-Fb-0Dq" firstAttribute="leading" secondItem="nCW-ER-9SF" secondAttribute="leading" id="wxI-iX-ugm"/>
|
||||
<constraint firstAttribute="height" constant="1" id="oFX-h1-fx7"/>
|
||||
</constraints>
|
||||
</view>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="trailing" secondItem="ztg-5t-ECh" secondAttribute="trailing" constant="20" id="ADS-wF-wRi"/>
|
||||
<constraint firstItem="ztg-5t-ECh" firstAttribute="leading" secondItem="DMT-DS-IA8" secondAttribute="leading" constant="20" id="YU9-Am-aht"/>
|
||||
<constraint firstAttribute="trailing" secondItem="Rn2-qe-htS" secondAttribute="trailing" constant="16" id="WIb-QJ-vx7"/>
|
||||
<constraint firstItem="bxI-mu-qng" firstAttribute="leading" secondItem="DMT-DS-IA8" secondAttribute="leading" constant="16" id="cg2-vW-LtI"/>
|
||||
<constraint firstAttribute="trailing" secondItem="bxI-mu-qng" secondAttribute="trailing" constant="16" id="j5H-f5-nqY"/>
|
||||
<constraint firstItem="Rn2-qe-htS" firstAttribute="leading" secondItem="DMT-DS-IA8" secondAttribute="leading" constant="16" id="y20-NI-Hl0"/>
|
||||
</constraints>
|
||||
</stackView>
|
||||
</subviews>
|
||||
|
@ -348,6 +326,7 @@
|
|||
<viewLayoutGuide key="safeArea" id="bFg-jh-JZB"/>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="bottomView" destination="N9V-f7-d5k" id="H5X-Px-d4w"/>
|
||||
<outlet property="digitsStackView" destination="W0M-eq-abZ" id="xnb-6w-dtC"/>
|
||||
<outlet property="explanatoryLabel" destination="Rn2-qe-htS" id="8WG-b4-nhE"/>
|
||||
<outlet property="forgotPinButton" destination="CRt-Fb-0Dq" id="kHp-wn-P0o"/>
|
||||
|
@ -364,7 +343,7 @@
|
|||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="zK0-v6-7Wt" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="-3199.1999999999998" y="-648.02955665024638"/>
|
||||
<point key="canvasLocation" x="-3199.1999999999998" y="-648.12593703148434"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
|
|
|
@ -42,6 +42,7 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
@IBOutlet private weak var informationLabel: UILabel!
|
||||
@IBOutlet private weak var explanatoryLabel: UILabel!
|
||||
@IBOutlet private weak var forgotPinButton: UIButton!
|
||||
@IBOutlet private weak var bottomView: UIView!
|
||||
|
||||
// MARK: Private
|
||||
|
||||
|
@ -160,6 +161,11 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
}
|
||||
|
||||
private func setupViews() {
|
||||
let cancelBarButtonItem = MXKBarButtonItem(title: VectorL10n.cancel, style: .plain) { [weak self] in
|
||||
self?.cancelButtonAction()
|
||||
}
|
||||
|
||||
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
|
||||
showCancelButton()
|
||||
|
||||
self.title = ""
|
||||
|
@ -177,15 +183,11 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
}
|
||||
|
||||
private func showCancelButton() {
|
||||
let cancelBarButtonItem = MXKBarButtonItem(title: VectorL10n.cancel, style: .plain) { [weak self] in
|
||||
self?.cancelButtonAction()
|
||||
}
|
||||
|
||||
self.navigationItem.rightBarButtonItem = cancelBarButtonItem
|
||||
self.navigationController?.navigationBar.isHidden = false
|
||||
}
|
||||
|
||||
private func hideCancelButton() {
|
||||
self.navigationItem.rightBarButtonItem = nil
|
||||
self.navigationController?.navigationBar.isHidden = true
|
||||
}
|
||||
|
||||
private func render(viewState: EnterPinCodeViewState) {
|
||||
|
@ -224,6 +226,7 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
self.informationLabel.text = VectorL10n.pinProtectionChoosePin
|
||||
self.explanatoryLabel.isHidden = false
|
||||
self.forgotPinButton.isHidden = true
|
||||
self.bottomView.isHidden = false
|
||||
self.notAllowedPinView.isHidden = true
|
||||
}
|
||||
|
||||
|
@ -242,6 +245,7 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
self.mainStackView.isHidden = false
|
||||
self.logoImageView.isHidden = true
|
||||
self.forgotPinButton.isHidden = true
|
||||
self.bottomView.isHidden = false
|
||||
self.notAllowedPinView.isHidden = false
|
||||
|
||||
renderPlaceholdersCount(.max, error: true)
|
||||
|
@ -273,8 +277,9 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
self.mainStackView.isHidden = false
|
||||
self.logoImageView.isHidden = false
|
||||
self.informationLabel.text = VectorL10n.pinProtectionEnterPin
|
||||
self.explanatoryLabel.text = nil
|
||||
self.explanatoryLabel.isHidden = true
|
||||
self.forgotPinButton.isHidden = false
|
||||
self.bottomView.isHidden = true
|
||||
self.notAllowedPinView.isHidden = true
|
||||
}
|
||||
|
||||
|
@ -282,7 +287,7 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
self.inactiveView.isHidden = true
|
||||
self.mainStackView.isHidden = false
|
||||
self.notAllowedPinView.isHidden = true
|
||||
self.explanatoryLabel.text = nil
|
||||
self.explanatoryLabel.isHidden = true
|
||||
self.placeholderStackView.vc_shake()
|
||||
}
|
||||
|
||||
|
@ -317,8 +322,9 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
self.mainStackView.isHidden = false
|
||||
self.logoImageView.isHidden = true
|
||||
self.informationLabel.text = VectorL10n.pinProtectionConfirmPinToDisable
|
||||
self.explanatoryLabel.text = nil
|
||||
self.explanatoryLabel.isHidden = true
|
||||
self.forgotPinButton.isHidden = true
|
||||
self.bottomView.isHidden = false
|
||||
self.notAllowedPinView.isHidden = true
|
||||
}
|
||||
|
||||
|
@ -327,7 +333,7 @@ final class EnterPinCodeViewController: UIViewController {
|
|||
self.inactiveView.isHidden = false
|
||||
self.mainStackView.isHidden = true
|
||||
self.notAllowedPinView.isHidden = true
|
||||
self.explanatoryLabel.text = nil
|
||||
self.explanatoryLabel.isHidden = true
|
||||
}
|
||||
|
||||
private func renderPlaceholdersCount(_ count: Int, error: Bool = false) {
|
||||
|
|
|
@ -114,6 +114,8 @@ enum {
|
|||
|
||||
}];
|
||||
[self userInterfaceThemeDidChange];
|
||||
|
||||
[self registerDeviceChangesNotification];
|
||||
}
|
||||
|
||||
- (void)userInterfaceThemeDidChange
|
||||
|
@ -247,6 +249,29 @@ enum {
|
|||
}
|
||||
|
||||
|
||||
#pragma mark - Data update
|
||||
|
||||
- (void)registerDeviceChangesNotification
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(onDeviceInfoTrustLevelDidChangeNotification:)
|
||||
name:MXDeviceInfoTrustLevelDidChangeNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)onDeviceInfoTrustLevelDidChangeNotification:(NSNotification*)notification
|
||||
{
|
||||
MXDeviceInfo *deviceInfo = notification.object;
|
||||
|
||||
NSString *deviceId = deviceInfo.deviceId;
|
||||
if ([deviceId isEqualToString:device.deviceId])
|
||||
{
|
||||
[self reloadDeviceWithCompletion:^{
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Segues
|
||||
|
||||
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
|
||||
|
|
|
@ -204,9 +204,11 @@ TableViewSectionsDelegate>
|
|||
}];
|
||||
[self userInterfaceThemeDidChange];
|
||||
|
||||
[self registerUserDevicesChangesNotification];
|
||||
|
||||
self.tableViewSections = [TableViewSections new];
|
||||
self.tableViewSections.delegate = self;
|
||||
|
||||
|
||||
[self updateSections];
|
||||
}
|
||||
|
||||
|
@ -559,6 +561,57 @@ TableViewSectionsDelegate>
|
|||
}
|
||||
|
||||
|
||||
#pragma mark - Data update
|
||||
|
||||
- (void)registerUserDevicesChangesNotification
|
||||
{
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(onDeviceInfoTrustLevelDidChangeNotification:)
|
||||
name:MXDeviceInfoTrustLevelDidChangeNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(crossSigningInfoTrustLevelDidChangeNotification:)
|
||||
name:MXCrossSigningInfoTrustLevelDidChangeNotification
|
||||
object:nil];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(onDidUpdateUsersDevicesNotification:)
|
||||
name:MXDeviceListDidUpdateUsersDevicesNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)onDidUpdateUsersDevicesNotification:(NSNotification*)notification
|
||||
{
|
||||
NSDictionary *usersDevices = notification.userInfo;
|
||||
|
||||
if ([usersDevices.allKeys containsObject:self.mainSession.myUserId])
|
||||
{
|
||||
[self loadDevices];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)onDeviceInfoTrustLevelDidChangeNotification:(NSNotification*)notification
|
||||
{
|
||||
MXDeviceInfo *deviceInfo = notification.object;
|
||||
|
||||
NSString *userId = deviceInfo.userId;
|
||||
if ([userId isEqualToString:self.mainSession.myUserId])
|
||||
{
|
||||
[self loadDevices];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)crossSigningInfoTrustLevelDidChangeNotification:(NSNotification*)notification
|
||||
{
|
||||
MXCrossSigningInfo *crossSigningInfo = notification.object;
|
||||
|
||||
NSString *userId = crossSigningInfo.userId;
|
||||
if ([userId isEqualToString:self.mainSession.myUserId])
|
||||
{
|
||||
[self loadDevices];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Cross-signing
|
||||
|
||||
- (void)loadCrossSigning
|
||||
|
|
|
@ -154,13 +154,24 @@ class NotificationService: UNNotificationServiceExtension {
|
|||
}
|
||||
}
|
||||
|
||||
func fetchEvent(withEventId eventId: String, roomId: String) {
|
||||
func fetchEvent(withEventId eventId: String, roomId: String, allowSync: Bool = true) {
|
||||
guard let mxSession = NotificationService.mxSession else {
|
||||
// there is something wrong, do not change the content
|
||||
NSLog("[NotificationService] fetchEvent: Either originalContent or mxSession is missing.")
|
||||
fallbackToBestAttemptContent(forEventId: eventId)
|
||||
return
|
||||
}
|
||||
|
||||
/// Inline function to handle decryption failure
|
||||
func handleDecryptionFailure() {
|
||||
if allowSync {
|
||||
NSLog("[NotificationService] fetchEvent: Launch a background sync.")
|
||||
self.launchBackgroundSync(forEventId: eventId, roomId: roomId)
|
||||
} else {
|
||||
NSLog("[NotificationService] fetchEvent: Do not sync anymore.")
|
||||
self.fallbackToBestAttemptContent(forEventId: eventId)
|
||||
}
|
||||
}
|
||||
|
||||
/// Inline function to handle encryption for event, either from cache or from the backend
|
||||
/// - Parameter event: The event to be handled
|
||||
|
@ -181,14 +192,22 @@ class NotificationService: UNNotificationServiceExtension {
|
|||
}
|
||||
|
||||
// should decrypt it first
|
||||
if mxSession.decryptEvent(event, inTimeline: nil) {
|
||||
// decryption succeeded
|
||||
NSLog("[NotificationService] fetchEvent: Event decrypted successfully.")
|
||||
self.processEvent(event)
|
||||
if mxSession.crypto.hasKeys(toDecryptEvent: event) {
|
||||
// we have keys to decrypt the event
|
||||
NSLog("[NotificationService] fetchEvent: Event needs to be decrpyted, and we have the keys to decrypt it.")
|
||||
if mxSession.decryptEvent(event, inTimeline: nil) {
|
||||
// decryption succeeded
|
||||
NSLog("[NotificationService] fetchEvent: Event decrypted successfully.")
|
||||
self.processEvent(event)
|
||||
} else {
|
||||
// decryption failed
|
||||
NSLog("[NotificationService] fetchEvent: Decryption failed even crypto claimed it has the keys.")
|
||||
handleDecryptionFailure()
|
||||
}
|
||||
} else {
|
||||
// decryption failed
|
||||
NSLog("[NotificationService] fetchEvent: Event needs to be decrpyted, but we don't have the keys to decrypt it. Launching a background sync.")
|
||||
self.launchBackgroundSync(forEventId: eventId, roomId: roomId)
|
||||
// we don't have keys to decrypt the event
|
||||
NSLog("[NotificationService] fetchEvent: Event needs to be decrpyted, but we don't have the keys to decrypt it.")
|
||||
handleDecryptionFailure()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -241,7 +260,8 @@ class NotificationService: UNNotificationServiceExtension {
|
|||
NSLog("[NotificationService] launchBackgroundSync: MXSession.initialBackgroundSync returned too late successfully")
|
||||
return
|
||||
}
|
||||
self.fetchEvent(withEventId: eventId, roomId: roomId)
|
||||
// do not allow to sync anymore
|
||||
self.fetchEvent(withEventId: eventId, roomId: roomId, allowSync: false)
|
||||
break
|
||||
case .failure(let error):
|
||||
guard let self = self else {
|
||||
|
|
Loading…
Reference in a new issue