diff --git a/.editorconfig b/.editorconfig index 1966f91763..60d4fd6cae 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,14 +1,901 @@ -# For ktlint configuration. Ref: https://ktlint.github.io/ +[*] +charset = utf-8 +end_of_line = crlf +indent_size = 4 +indent_style = space +insert_final_newline = true +max_line_length = 160 +tab_width = 4 +ij_continuation_indent_size = 8 +ij_formatter_off_tag = @formatter:off +ij_formatter_on_tag = @formatter:on +ij_formatter_tags_enabled = false +ij_smart_tabs = false +ij_visual_guides = none +ij_wrap_on_typing = false -[*.{kt,kts}] -# possible values: number (e.g. 2), "unset" (makes ktlint ignore indentation completely) -indent_size=unset -# true (recommended) / false -insert_final_newline=true -# possible values: number (e.g. 120) (package name, imports & comments are ignored), "off" -# it's automatically set to 100 on `ktlint --android ...` (per Android Kotlin Style Guide) -max_line_length=off +[*.java] +ij_java_align_consecutive_assignments = false +ij_java_align_consecutive_variable_declarations = false +ij_java_align_group_field_declarations = false +ij_java_align_multiline_annotation_parameters = false +ij_java_align_multiline_array_initializer_expression = false +ij_java_align_multiline_assignment = false +ij_java_align_multiline_binary_operation = false +ij_java_align_multiline_chained_methods = false +ij_java_align_multiline_extends_list = false +ij_java_align_multiline_for = true +ij_java_align_multiline_method_parentheses = false +ij_java_align_multiline_parameters = true +ij_java_align_multiline_parameters_in_calls = false +ij_java_align_multiline_parenthesized_expression = false +ij_java_align_multiline_records = true +ij_java_align_multiline_resources = true +ij_java_align_multiline_ternary_operation = false +ij_java_align_multiline_text_blocks = false +ij_java_align_multiline_throws_list = false +ij_java_align_subsequent_simple_methods = false +ij_java_align_throws_keyword = false +ij_java_annotation_parameter_wrap = off +ij_java_array_initializer_new_line_after_left_brace = false +ij_java_array_initializer_right_brace_on_new_line = false +ij_java_array_initializer_wrap = off +ij_java_assert_statement_colon_on_next_line = false +ij_java_assert_statement_wrap = off +ij_java_assignment_wrap = off +ij_java_binary_operation_sign_on_next_line = false +ij_java_binary_operation_wrap = off +ij_java_blank_lines_after_anonymous_class_header = 0 +ij_java_blank_lines_after_class_header = 0 +ij_java_blank_lines_after_imports = 1 +ij_java_blank_lines_after_package = 1 +ij_java_blank_lines_around_class = 1 +ij_java_blank_lines_around_field = 0 +ij_java_blank_lines_around_field_in_interface = 0 +ij_java_blank_lines_around_initializer = 1 +ij_java_blank_lines_around_method = 1 +ij_java_blank_lines_around_method_in_interface = 1 +ij_java_blank_lines_before_class_end = 0 +ij_java_blank_lines_before_imports = 1 +ij_java_blank_lines_before_method_body = 0 +ij_java_blank_lines_before_package = 0 +ij_java_block_brace_style = end_of_line +ij_java_block_comment_at_first_column = true +ij_java_builder_methods = none +ij_java_call_parameters_new_line_after_left_paren = false +ij_java_call_parameters_right_paren_on_new_line = false +ij_java_call_parameters_wrap = off +ij_java_case_statement_on_separate_line = true +ij_java_catch_on_new_line = false +ij_java_class_annotation_wrap = split_into_lines +ij_java_class_brace_style = end_of_line +ij_java_class_count_to_use_import_on_demand = 99 +ij_java_class_names_in_javadoc = 1 +ij_java_do_not_indent_top_level_class_members = false +ij_java_do_not_wrap_after_single_annotation = false +ij_java_do_while_brace_force = never +ij_java_doc_add_blank_line_after_description = true +ij_java_doc_add_blank_line_after_param_comments = false +ij_java_doc_add_blank_line_after_return = false +ij_java_doc_add_p_tag_on_empty_lines = true +ij_java_doc_align_exception_comments = true +ij_java_doc_align_param_comments = true +ij_java_doc_do_not_wrap_if_one_line = false +ij_java_doc_enable_formatting = true +ij_java_doc_enable_leading_asterisks = true +ij_java_doc_indent_on_continuation = false +ij_java_doc_keep_empty_lines = true +ij_java_doc_keep_empty_parameter_tag = true +ij_java_doc_keep_empty_return_tag = true +ij_java_doc_keep_empty_throws_tag = true +ij_java_doc_keep_invalid_tags = true +ij_java_doc_param_description_on_new_line = false +ij_java_doc_preserve_line_breaks = false +ij_java_doc_use_throws_not_exception_tag = true +ij_java_else_on_new_line = false +ij_java_enum_constants_wrap = off +ij_java_extends_keyword_wrap = off +ij_java_extends_list_wrap = off +ij_java_field_annotation_wrap = split_into_lines +ij_java_finally_on_new_line = false +ij_java_for_brace_force = never +ij_java_for_statement_new_line_after_left_paren = false +ij_java_for_statement_right_paren_on_new_line = false +ij_java_for_statement_wrap = off +ij_java_generate_final_locals = false +ij_java_generate_final_parameters = false +ij_java_if_brace_force = never +ij_java_imports_layout = $android.**,$androidx.**,$com.**,$junit.**,$net.**,$org.**,$java.**,$javax.**,$*,|,android.**,|,androidx.**,|,com.**,|,junit.**,|,net.**,|,org.**,|,java.**,|,javax.**,|,*,| +ij_java_indent_case_from_switch = true +ij_java_insert_inner_class_imports = false +ij_java_insert_override_annotation = true +ij_java_keep_blank_lines_before_right_brace = 2 +ij_java_keep_blank_lines_between_package_declaration_and_header = 2 +ij_java_keep_blank_lines_in_code = 2 +ij_java_keep_blank_lines_in_declarations = 2 +ij_java_keep_builder_methods_indents = false +ij_java_keep_control_statement_in_one_line = true +ij_java_keep_first_column_comment = true +ij_java_keep_indents_on_empty_lines = false +ij_java_keep_line_breaks = true +ij_java_keep_multiple_expressions_in_one_line = false +ij_java_keep_simple_blocks_in_one_line = false +ij_java_keep_simple_classes_in_one_line = false +ij_java_keep_simple_lambdas_in_one_line = false +ij_java_keep_simple_methods_in_one_line = false +ij_java_label_indent_absolute = false +ij_java_label_indent_size = 0 +ij_java_lambda_brace_style = end_of_line +ij_java_layout_static_imports_separately = true +ij_java_line_comment_add_space = false +ij_java_line_comment_at_first_column = true +ij_java_method_annotation_wrap = split_into_lines +ij_java_method_brace_style = end_of_line +ij_java_method_call_chain_wrap = off +ij_java_method_parameters_new_line_after_left_paren = false +ij_java_method_parameters_right_paren_on_new_line = false +ij_java_method_parameters_wrap = off +ij_java_modifier_list_wrap = false +ij_java_names_count_to_use_import_on_demand = 99 +ij_java_new_line_after_lparen_in_record_header = false +ij_java_parameter_annotation_wrap = off +ij_java_parentheses_expression_new_line_after_left_paren = false +ij_java_parentheses_expression_right_paren_on_new_line = false +ij_java_place_assignment_sign_on_next_line = false +ij_java_prefer_longer_names = true +ij_java_prefer_parameters_wrap = false +ij_java_record_components_wrap = normal +ij_java_repeat_synchronized = true +ij_java_replace_instanceof_and_cast = false +ij_java_replace_null_check = true +ij_java_replace_sum_lambda_with_method_ref = true +ij_java_resource_list_new_line_after_left_paren = false +ij_java_resource_list_right_paren_on_new_line = false +ij_java_resource_list_wrap = off +ij_java_rparen_on_new_line_in_record_header = false +ij_java_space_after_closing_angle_bracket_in_type_argument = false +ij_java_space_after_colon = true +ij_java_space_after_comma = true +ij_java_space_after_comma_in_type_arguments = true +ij_java_space_after_for_semicolon = true +ij_java_space_after_quest = true +ij_java_space_after_type_cast = true +ij_java_space_before_annotation_array_initializer_left_brace = false +ij_java_space_before_annotation_parameter_list = false +ij_java_space_before_array_initializer_left_brace = false +ij_java_space_before_catch_keyword = true +ij_java_space_before_catch_left_brace = true +ij_java_space_before_catch_parentheses = true +ij_java_space_before_class_left_brace = true +ij_java_space_before_colon = true +ij_java_space_before_colon_in_foreach = true +ij_java_space_before_comma = false +ij_java_space_before_do_left_brace = true +ij_java_space_before_else_keyword = true +ij_java_space_before_else_left_brace = true +ij_java_space_before_finally_keyword = true +ij_java_space_before_finally_left_brace = true +ij_java_space_before_for_left_brace = true +ij_java_space_before_for_parentheses = true +ij_java_space_before_for_semicolon = false +ij_java_space_before_if_left_brace = true +ij_java_space_before_if_parentheses = true +ij_java_space_before_method_call_parentheses = false +ij_java_space_before_method_left_brace = true +ij_java_space_before_method_parentheses = false +ij_java_space_before_opening_angle_bracket_in_type_parameter = false +ij_java_space_before_quest = true +ij_java_space_before_switch_left_brace = true +ij_java_space_before_switch_parentheses = true +ij_java_space_before_synchronized_left_brace = true +ij_java_space_before_synchronized_parentheses = true +ij_java_space_before_try_left_brace = true +ij_java_space_before_try_parentheses = true +ij_java_space_before_type_parameter_list = false +ij_java_space_before_while_keyword = true +ij_java_space_before_while_left_brace = true +ij_java_space_before_while_parentheses = true +ij_java_space_inside_one_line_enum_braces = false +ij_java_space_within_empty_array_initializer_braces = false +ij_java_space_within_empty_method_call_parentheses = false +ij_java_space_within_empty_method_parentheses = false +ij_java_spaces_around_additive_operators = true +ij_java_spaces_around_assignment_operators = true +ij_java_spaces_around_bitwise_operators = true +ij_java_spaces_around_equality_operators = true +ij_java_spaces_around_lambda_arrow = true +ij_java_spaces_around_logical_operators = true +ij_java_spaces_around_method_ref_dbl_colon = false +ij_java_spaces_around_multiplicative_operators = true +ij_java_spaces_around_relational_operators = true +ij_java_spaces_around_shift_operators = true +ij_java_spaces_around_type_bounds_in_type_parameters = true +ij_java_spaces_around_unary_operator = false +ij_java_spaces_within_angle_brackets = false +ij_java_spaces_within_annotation_parentheses = false +ij_java_spaces_within_array_initializer_braces = false +ij_java_spaces_within_braces = false +ij_java_spaces_within_brackets = false +ij_java_spaces_within_cast_parentheses = false +ij_java_spaces_within_catch_parentheses = false +ij_java_spaces_within_for_parentheses = false +ij_java_spaces_within_if_parentheses = false +ij_java_spaces_within_method_call_parentheses = false +ij_java_spaces_within_method_parentheses = false +ij_java_spaces_within_parentheses = false +ij_java_spaces_within_record_header = false +ij_java_spaces_within_switch_parentheses = false +ij_java_spaces_within_synchronized_parentheses = false +ij_java_spaces_within_try_parentheses = false +ij_java_spaces_within_while_parentheses = false +ij_java_special_else_if_treatment = true +ij_java_subclass_name_suffix = Impl +ij_java_ternary_operation_signs_on_next_line = false +ij_java_ternary_operation_wrap = off +ij_java_test_name_suffix = Test +ij_java_throws_keyword_wrap = off +ij_java_throws_list_wrap = off +ij_java_use_external_annotations = false +ij_java_use_fq_class_names = false +ij_java_use_relative_indents = false +ij_java_use_single_class_imports = true +ij_java_variable_annotation_wrap = off +ij_java_visibility = public +ij_java_while_brace_force = never +ij_java_while_on_new_line = false +ij_java_wrap_comments = false +ij_java_wrap_first_method_in_call_chain = false +ij_java_wrap_long_lines = false -# From https://github.com/pinterest/ktlint#custom-ktlint-specific-editorconfig-properties -# default IntelliJ IDEA style, same as alphabetical, but with "java", "javax", "kotlin" and alias imports in the end of the imports list -ij_kotlin_imports_layout=*,java.**,javax.**,kotlin.**,^ +[*.properties] +ij_properties_align_group_field_declarations = false +ij_properties_keep_blank_lines = false +ij_properties_key_value_delimiter = equals +ij_properties_spaces_around_key_value_delimiter = false + +[.editorconfig] +ij_editorconfig_align_group_field_declarations = false +ij_editorconfig_space_after_colon = false +ij_editorconfig_space_after_comma = true +ij_editorconfig_space_before_colon = false +ij_editorconfig_space_before_comma = false +ij_editorconfig_spaces_around_assignment_operators = true + +[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.rng,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}] +ij_continuation_indent_size = 4 +ij_xml_align_attributes = false +ij_xml_align_text = false +ij_xml_attribute_wrap = normal +ij_xml_block_comment_at_first_column = true +ij_xml_keep_blank_lines = 2 +ij_xml_keep_indents_on_empty_lines = false +ij_xml_keep_line_breaks = false +ij_xml_keep_line_breaks_in_text = true +ij_xml_keep_whitespaces = false +ij_xml_keep_whitespaces_around_cdata = preserve +ij_xml_keep_whitespaces_inside_cdata = false +ij_xml_line_comment_at_first_column = true +ij_xml_space_after_tag_name = false +ij_xml_space_around_equals_in_attribute = false +ij_xml_space_inside_empty_tag = true +ij_xml_text_wrap = normal +ij_xml_use_custom_settings = true + +[{*.bash,*.sh,*.zsh}] +indent_size = 2 +tab_width = 2 +ij_shell_binary_ops_start_line = false +ij_shell_keep_column_alignment_padding = false +ij_shell_minify_program = false +ij_shell_redirect_followed_by_space = false +ij_shell_switch_cases_indented = false +ij_shell_use_unix_line_separator = true + +[{*.c,*.c++,*.cc,*.cp,*.cpp,*.cu,*.cuh,*.cxx,*.h,*.h++,*.hh,*.hp,*.hpp,*.hxx,*.i,*.icc,*.ii,*.inl,*.ino,*.ipp,*.m,*.mm,*.pch,*.tcc,*.tpp}] +ij_c_add_brief_tag = false +ij_c_add_getter_prefix = true +ij_c_add_setter_prefix = true +ij_c_align_dictionary_pair_values = false +ij_c_align_group_field_declarations = false +ij_c_align_init_list_in_columns = true +ij_c_align_multiline_array_initializer_expression = true +ij_c_align_multiline_assignment = true +ij_c_align_multiline_binary_operation = true +ij_c_align_multiline_chained_methods = false +ij_c_align_multiline_for = true +ij_c_align_multiline_ternary_operation = true +ij_c_array_initializer_comma_on_next_line = false +ij_c_array_initializer_new_line_after_left_brace = false +ij_c_array_initializer_right_brace_on_new_line = false +ij_c_array_initializer_wrap = normal +ij_c_assignment_wrap = off +ij_c_binary_operation_sign_on_next_line = false +ij_c_binary_operation_wrap = normal +ij_c_blank_lines_after_class_header = 0 +ij_c_blank_lines_after_imports = 1 +ij_c_blank_lines_around_class = 1 +ij_c_blank_lines_around_field = 0 +ij_c_blank_lines_around_field_in_interface = 0 +ij_c_blank_lines_around_method = 1 +ij_c_blank_lines_around_method_in_interface = 1 +ij_c_blank_lines_around_namespace = 0 +ij_c_blank_lines_around_properties_in_declaration = 0 +ij_c_blank_lines_around_properties_in_interface = 0 +ij_c_blank_lines_before_imports = 1 +ij_c_blank_lines_before_method_body = 0 +ij_c_block_brace_placement = end_of_line +ij_c_block_brace_style = end_of_line +ij_c_block_comment_at_first_column = true +ij_c_catch_on_new_line = false +ij_c_class_brace_style = end_of_line +ij_c_class_constructor_init_list_align_multiline = true +ij_c_class_constructor_init_list_comma_on_next_line = false +ij_c_class_constructor_init_list_new_line_after_colon = never +ij_c_class_constructor_init_list_new_line_before_colon = if_long +ij_c_class_constructor_init_list_wrap = normal +ij_c_copy_is_deep = false +ij_c_create_interface_for_categories = true +ij_c_declare_generated_methods = true +ij_c_description_include_member_names = true +ij_c_discharged_short_ternary_operator = false +ij_c_do_not_add_breaks = false +ij_c_do_while_brace_force = never +ij_c_else_on_new_line = false +ij_c_enum_constants_comma_on_next_line = false +ij_c_enum_constants_wrap = on_every_item +ij_c_for_brace_force = never +ij_c_for_statement_new_line_after_left_paren = false +ij_c_for_statement_right_paren_on_new_line = false +ij_c_for_statement_wrap = off +ij_c_function_brace_placement = end_of_line +ij_c_function_call_arguments_align_multiline = true +ij_c_function_call_arguments_align_multiline_pars = false +ij_c_function_call_arguments_comma_on_next_line = false +ij_c_function_call_arguments_new_line_after_lpar = false +ij_c_function_call_arguments_new_line_before_rpar = false +ij_c_function_call_arguments_wrap = normal +ij_c_function_non_top_after_return_type_wrap = normal +ij_c_function_parameters_align_multiline = true +ij_c_function_parameters_align_multiline_pars = false +ij_c_function_parameters_comma_on_next_line = false +ij_c_function_parameters_new_line_after_lpar = false +ij_c_function_parameters_new_line_before_rpar = false +ij_c_function_parameters_wrap = normal +ij_c_function_top_after_return_type_wrap = normal +ij_c_generate_additional_eq_operators = true +ij_c_generate_additional_rel_operators = true +ij_c_generate_class_constructor = true +ij_c_generate_comparison_operators_use_std_tie = false +ij_c_generate_instance_variables_for_properties = ask +ij_c_generate_operators_as_members = true +ij_c_header_guard_style_pattern = ${PROJECT_NAME}_${FILE_NAME}_${EXT} +ij_c_if_brace_force = never +ij_c_in_line_short_ternary_operator = true +ij_c_indent_block_comment = true +ij_c_indent_c_struct_members = 4 +ij_c_indent_case_from_switch = true +ij_c_indent_class_members = 4 +ij_c_indent_directive_as_code = false +ij_c_indent_implementation_members = 0 +ij_c_indent_inside_code_block = 4 +ij_c_indent_interface_members = 0 +ij_c_indent_interface_members_except_ivars_block = false +ij_c_indent_namespace_members = 4 +ij_c_indent_preprocessor_directive = 0 +ij_c_indent_visibility_keywords = 0 +ij_c_insert_override = true +ij_c_insert_virtual_with_override = false +ij_c_introduce_auto_vars = false +ij_c_introduce_const_params = false +ij_c_introduce_const_vars = false +ij_c_introduce_generate_property = false +ij_c_introduce_generate_synthesize = true +ij_c_introduce_globals_to_header = true +ij_c_introduce_prop_to_private_category = false +ij_c_introduce_static_consts = true +ij_c_introduce_use_ns_types = false +ij_c_ivars_prefix = _ +ij_c_keep_blank_lines_before_end = 2 +ij_c_keep_blank_lines_before_right_brace = 2 +ij_c_keep_blank_lines_in_code = 2 +ij_c_keep_blank_lines_in_declarations = 2 +ij_c_keep_case_expressions_in_one_line = false +ij_c_keep_control_statement_in_one_line = true +ij_c_keep_directive_at_first_column = true +ij_c_keep_first_column_comment = true +ij_c_keep_line_breaks = true +ij_c_keep_nested_namespaces_in_one_line = false +ij_c_keep_simple_blocks_in_one_line = true +ij_c_keep_simple_methods_in_one_line = true +ij_c_keep_structures_in_one_line = false +ij_c_lambda_capture_list_align_multiline = false +ij_c_lambda_capture_list_align_multiline_bracket = false +ij_c_lambda_capture_list_comma_on_next_line = false +ij_c_lambda_capture_list_new_line_after_lbracket = false +ij_c_lambda_capture_list_new_line_before_rbracket = false +ij_c_lambda_capture_list_wrap = off +ij_c_line_comment_add_space = false +ij_c_line_comment_at_first_column = true +ij_c_method_brace_placement = end_of_line +ij_c_method_call_arguments_align_by_colons = true +ij_c_method_call_arguments_align_multiline = false +ij_c_method_call_arguments_special_dictionary_pairs_treatment = true +ij_c_method_call_arguments_wrap = off +ij_c_method_call_chain_wrap = off +ij_c_method_parameters_align_by_colons = true +ij_c_method_parameters_align_multiline = false +ij_c_method_parameters_wrap = off +ij_c_namespace_brace_placement = end_of_line +ij_c_parentheses_expression_new_line_after_left_paren = false +ij_c_parentheses_expression_right_paren_on_new_line = false +ij_c_place_assignment_sign_on_next_line = false +ij_c_property_nonatomic = true +ij_c_put_ivars_to_implementation = true +ij_c_refactor_compatibility_aliases_and_classes = true +ij_c_refactor_properties_and_ivars = true +ij_c_release_style = ivar +ij_c_retain_object_parameters_in_constructor = true +ij_c_semicolon_after_method_signature = false +ij_c_shift_operation_align_multiline = true +ij_c_shift_operation_wrap = normal +ij_c_show_non_virtual_functions = false +ij_c_space_after_colon = true +ij_c_space_after_colon_in_selector = false +ij_c_space_after_comma = true +ij_c_space_after_cup_in_blocks = false +ij_c_space_after_dictionary_literal_colon = true +ij_c_space_after_for_semicolon = true +ij_c_space_after_init_list_colon = true +ij_c_space_after_method_parameter_type_parentheses = false +ij_c_space_after_method_return_type_parentheses = false +ij_c_space_after_pointer_in_declaration = false +ij_c_space_after_quest = true +ij_c_space_after_reference_in_declaration = false +ij_c_space_after_reference_in_rvalue = false +ij_c_space_after_structures_rbrace = true +ij_c_space_after_superclass_colon = true +ij_c_space_after_type_cast = true +ij_c_space_after_visibility_sign_in_method_declaration = true +ij_c_space_before_autorelease_pool_lbrace = true +ij_c_space_before_catch_keyword = true +ij_c_space_before_catch_left_brace = true +ij_c_space_before_catch_parentheses = true +ij_c_space_before_category_parentheses = true +ij_c_space_before_chained_send_message = true +ij_c_space_before_class_left_brace = true +ij_c_space_before_colon = true +ij_c_space_before_comma = false +ij_c_space_before_dictionary_literal_colon = false +ij_c_space_before_do_left_brace = true +ij_c_space_before_else_keyword = true +ij_c_space_before_else_left_brace = true +ij_c_space_before_for_left_brace = true +ij_c_space_before_for_parentheses = true +ij_c_space_before_for_semicolon = false +ij_c_space_before_if_left_brace = true +ij_c_space_before_if_parentheses = true +ij_c_space_before_init_list = false +ij_c_space_before_init_list_colon = true +ij_c_space_before_method_call_parentheses = false +ij_c_space_before_method_left_brace = true +ij_c_space_before_method_parentheses = false +ij_c_space_before_namespace_lbrace = true +ij_c_space_before_pointer_in_declaration = true +ij_c_space_before_property_attributes_parentheses = false +ij_c_space_before_protocols_brackets = true +ij_c_space_before_quest = true +ij_c_space_before_reference_in_declaration = true +ij_c_space_before_superclass_colon = true +ij_c_space_before_switch_left_brace = true +ij_c_space_before_switch_parentheses = true +ij_c_space_before_template_call_lt = false +ij_c_space_before_template_declaration_lt = false +ij_c_space_before_try_left_brace = true +ij_c_space_before_while_keyword = true +ij_c_space_before_while_left_brace = true +ij_c_space_before_while_parentheses = true +ij_c_space_between_adjacent_brackets = false +ij_c_space_between_operator_and_punctuator = false +ij_c_space_within_empty_array_initializer_braces = false +ij_c_spaces_around_additive_operators = true +ij_c_spaces_around_assignment_operators = true +ij_c_spaces_around_bitwise_operators = true +ij_c_spaces_around_equality_operators = true +ij_c_spaces_around_lambda_arrow = true +ij_c_spaces_around_logical_operators = true +ij_c_spaces_around_multiplicative_operators = true +ij_c_spaces_around_pm_operators = false +ij_c_spaces_around_relational_operators = true +ij_c_spaces_around_shift_operators = true +ij_c_spaces_around_unary_operator = false +ij_c_spaces_within_array_initializer_braces = false +ij_c_spaces_within_braces = true +ij_c_spaces_within_brackets = false +ij_c_spaces_within_cast_parentheses = false +ij_c_spaces_within_catch_parentheses = false +ij_c_spaces_within_category_parentheses = false +ij_c_spaces_within_empty_braces = false +ij_c_spaces_within_empty_function_call_parentheses = false +ij_c_spaces_within_empty_function_declaration_parentheses = false +ij_c_spaces_within_empty_lambda_capture_list_bracket = false +ij_c_spaces_within_empty_template_call_ltgt = false +ij_c_spaces_within_empty_template_declaration_ltgt = false +ij_c_spaces_within_for_parentheses = false +ij_c_spaces_within_function_call_parentheses = false +ij_c_spaces_within_function_declaration_parentheses = false +ij_c_spaces_within_if_parentheses = false +ij_c_spaces_within_lambda_capture_list_bracket = false +ij_c_spaces_within_method_parameter_type_parentheses = false +ij_c_spaces_within_method_return_type_parentheses = false +ij_c_spaces_within_parentheses = false +ij_c_spaces_within_property_attributes_parentheses = false +ij_c_spaces_within_protocols_brackets = false +ij_c_spaces_within_send_message_brackets = false +ij_c_spaces_within_switch_parentheses = false +ij_c_spaces_within_template_call_ltgt = false +ij_c_spaces_within_template_declaration_ltgt = false +ij_c_spaces_within_template_double_gt = true +ij_c_spaces_within_while_parentheses = false +ij_c_special_else_if_treatment = true +ij_c_superclass_list_after_colon = never +ij_c_superclass_list_align_multiline = true +ij_c_superclass_list_before_colon = if_long +ij_c_superclass_list_comma_on_next_line = false +ij_c_superclass_list_wrap = on_every_item +ij_c_tag_prefix_of_block_comment = at +ij_c_tag_prefix_of_line_comment = back_slash +ij_c_template_call_arguments_align_multiline = false +ij_c_template_call_arguments_align_multiline_pars = false +ij_c_template_call_arguments_comma_on_next_line = false +ij_c_template_call_arguments_new_line_after_lt = false +ij_c_template_call_arguments_new_line_before_gt = false +ij_c_template_call_arguments_wrap = off +ij_c_template_declaration_function_body_indent = false +ij_c_template_declaration_function_wrap = split_into_lines +ij_c_template_declaration_struct_body_indent = false +ij_c_template_declaration_struct_wrap = split_into_lines +ij_c_template_parameters_align_multiline = false +ij_c_template_parameters_align_multiline_pars = false +ij_c_template_parameters_comma_on_next_line = false +ij_c_template_parameters_new_line_after_lt = false +ij_c_template_parameters_new_line_before_gt = false +ij_c_template_parameters_wrap = off +ij_c_ternary_operation_signs_on_next_line = true +ij_c_ternary_operation_wrap = normal +ij_c_type_qualifiers_placement = before +ij_c_use_modern_casts = true +ij_c_use_setters_in_constructor = true +ij_c_while_brace_force = never +ij_c_while_on_new_line = false +ij_c_wrap_property_declaration = off + +[{*.cmake,CMakeLists.txt}] +ij_cmake_align_multiline_parameters_in_calls = false +ij_cmake_force_commands_case = 2 +ij_cmake_keep_blank_lines_in_code = 2 +ij_cmake_space_before_for_parentheses = true +ij_cmake_space_before_if_parentheses = true +ij_cmake_space_before_method_call_parentheses = false +ij_cmake_space_before_method_parentheses = false +ij_cmake_space_before_while_parentheses = true +ij_cmake_spaces_within_for_parentheses = false +ij_cmake_spaces_within_if_parentheses = false +ij_cmake_spaces_within_method_call_parentheses = false +ij_cmake_spaces_within_method_parentheses = false +ij_cmake_spaces_within_while_parentheses = false + +[{*.gant,*.gradle,*.groovy,*.gy}] +ij_groovy_align_group_field_declarations = false +ij_groovy_align_multiline_array_initializer_expression = false +ij_groovy_align_multiline_assignment = false +ij_groovy_align_multiline_binary_operation = false +ij_groovy_align_multiline_chained_methods = false +ij_groovy_align_multiline_extends_list = false +ij_groovy_align_multiline_for = true +ij_groovy_align_multiline_list_or_map = true +ij_groovy_align_multiline_method_parentheses = false +ij_groovy_align_multiline_parameters = true +ij_groovy_align_multiline_parameters_in_calls = false +ij_groovy_align_multiline_resources = true +ij_groovy_align_multiline_ternary_operation = false +ij_groovy_align_multiline_throws_list = false +ij_groovy_align_named_args_in_map = true +ij_groovy_align_throws_keyword = false +ij_groovy_array_initializer_new_line_after_left_brace = false +ij_groovy_array_initializer_right_brace_on_new_line = false +ij_groovy_array_initializer_wrap = off +ij_groovy_assert_statement_wrap = off +ij_groovy_assignment_wrap = off +ij_groovy_binary_operation_wrap = off +ij_groovy_blank_lines_after_class_header = 0 +ij_groovy_blank_lines_after_imports = 1 +ij_groovy_blank_lines_after_package = 1 +ij_groovy_blank_lines_around_class = 1 +ij_groovy_blank_lines_around_field = 0 +ij_groovy_blank_lines_around_field_in_interface = 0 +ij_groovy_blank_lines_around_method = 1 +ij_groovy_blank_lines_around_method_in_interface = 1 +ij_groovy_blank_lines_before_imports = 1 +ij_groovy_blank_lines_before_method_body = 0 +ij_groovy_blank_lines_before_package = 0 +ij_groovy_block_brace_style = end_of_line +ij_groovy_block_comment_at_first_column = true +ij_groovy_call_parameters_new_line_after_left_paren = false +ij_groovy_call_parameters_right_paren_on_new_line = false +ij_groovy_call_parameters_wrap = off +ij_groovy_catch_on_new_line = false +ij_groovy_class_annotation_wrap = split_into_lines +ij_groovy_class_brace_style = end_of_line +ij_groovy_class_count_to_use_import_on_demand = 5 +ij_groovy_do_while_brace_force = never +ij_groovy_else_on_new_line = false +ij_groovy_enum_constants_wrap = off +ij_groovy_extends_keyword_wrap = off +ij_groovy_extends_list_wrap = off +ij_groovy_field_annotation_wrap = split_into_lines +ij_groovy_finally_on_new_line = false +ij_groovy_for_brace_force = never +ij_groovy_for_statement_new_line_after_left_paren = false +ij_groovy_for_statement_right_paren_on_new_line = false +ij_groovy_for_statement_wrap = off +ij_groovy_if_brace_force = never +ij_groovy_import_annotation_wrap = 2 +ij_groovy_imports_layout = *,|,javax.**,java.**,|,$* +ij_groovy_indent_case_from_switch = true +ij_groovy_indent_label_blocks = true +ij_groovy_insert_inner_class_imports = false +ij_groovy_keep_blank_lines_before_right_brace = 2 +ij_groovy_keep_blank_lines_in_code = 2 +ij_groovy_keep_blank_lines_in_declarations = 2 +ij_groovy_keep_control_statement_in_one_line = true +ij_groovy_keep_first_column_comment = true +ij_groovy_keep_indents_on_empty_lines = false +ij_groovy_keep_line_breaks = true +ij_groovy_keep_multiple_expressions_in_one_line = false +ij_groovy_keep_simple_blocks_in_one_line = false +ij_groovy_keep_simple_classes_in_one_line = true +ij_groovy_keep_simple_lambdas_in_one_line = true +ij_groovy_keep_simple_methods_in_one_line = true +ij_groovy_label_indent_absolute = false +ij_groovy_label_indent_size = 0 +ij_groovy_lambda_brace_style = end_of_line +ij_groovy_layout_static_imports_separately = true +ij_groovy_line_comment_add_space = false +ij_groovy_line_comment_at_first_column = true +ij_groovy_method_annotation_wrap = split_into_lines +ij_groovy_method_brace_style = end_of_line +ij_groovy_method_call_chain_wrap = off +ij_groovy_method_parameters_new_line_after_left_paren = false +ij_groovy_method_parameters_right_paren_on_new_line = false +ij_groovy_method_parameters_wrap = off +ij_groovy_modifier_list_wrap = false +ij_groovy_names_count_to_use_import_on_demand = 3 +ij_groovy_parameter_annotation_wrap = off +ij_groovy_parentheses_expression_new_line_after_left_paren = false +ij_groovy_parentheses_expression_right_paren_on_new_line = false +ij_groovy_prefer_parameters_wrap = false +ij_groovy_resource_list_new_line_after_left_paren = false +ij_groovy_resource_list_right_paren_on_new_line = false +ij_groovy_resource_list_wrap = off +ij_groovy_space_after_assert_separator = true +ij_groovy_space_after_colon = true +ij_groovy_space_after_comma = true +ij_groovy_space_after_comma_in_type_arguments = true +ij_groovy_space_after_for_semicolon = true +ij_groovy_space_after_quest = true +ij_groovy_space_after_type_cast = true +ij_groovy_space_before_annotation_parameter_list = false +ij_groovy_space_before_array_initializer_left_brace = false +ij_groovy_space_before_assert_separator = false +ij_groovy_space_before_catch_keyword = true +ij_groovy_space_before_catch_left_brace = true +ij_groovy_space_before_catch_parentheses = true +ij_groovy_space_before_class_left_brace = true +ij_groovy_space_before_closure_left_brace = true +ij_groovy_space_before_colon = true +ij_groovy_space_before_comma = false +ij_groovy_space_before_do_left_brace = true +ij_groovy_space_before_else_keyword = true +ij_groovy_space_before_else_left_brace = true +ij_groovy_space_before_finally_keyword = true +ij_groovy_space_before_finally_left_brace = true +ij_groovy_space_before_for_left_brace = true +ij_groovy_space_before_for_parentheses = true +ij_groovy_space_before_for_semicolon = false +ij_groovy_space_before_if_left_brace = true +ij_groovy_space_before_if_parentheses = true +ij_groovy_space_before_method_call_parentheses = false +ij_groovy_space_before_method_left_brace = true +ij_groovy_space_before_method_parentheses = false +ij_groovy_space_before_quest = true +ij_groovy_space_before_switch_left_brace = true +ij_groovy_space_before_switch_parentheses = true +ij_groovy_space_before_synchronized_left_brace = true +ij_groovy_space_before_synchronized_parentheses = true +ij_groovy_space_before_try_left_brace = true +ij_groovy_space_before_try_parentheses = true +ij_groovy_space_before_while_keyword = true +ij_groovy_space_before_while_left_brace = true +ij_groovy_space_before_while_parentheses = true +ij_groovy_space_in_named_argument = true +ij_groovy_space_in_named_argument_before_colon = false +ij_groovy_space_within_empty_array_initializer_braces = false +ij_groovy_space_within_empty_method_call_parentheses = false +ij_groovy_spaces_around_additive_operators = true +ij_groovy_spaces_around_assignment_operators = true +ij_groovy_spaces_around_bitwise_operators = true +ij_groovy_spaces_around_equality_operators = true +ij_groovy_spaces_around_lambda_arrow = true +ij_groovy_spaces_around_logical_operators = true +ij_groovy_spaces_around_multiplicative_operators = true +ij_groovy_spaces_around_regex_operators = true +ij_groovy_spaces_around_relational_operators = true +ij_groovy_spaces_around_shift_operators = true +ij_groovy_spaces_within_annotation_parentheses = false +ij_groovy_spaces_within_array_initializer_braces = false +ij_groovy_spaces_within_braces = true +ij_groovy_spaces_within_brackets = false +ij_groovy_spaces_within_cast_parentheses = false +ij_groovy_spaces_within_catch_parentheses = false +ij_groovy_spaces_within_for_parentheses = false +ij_groovy_spaces_within_gstring_injection_braces = false +ij_groovy_spaces_within_if_parentheses = false +ij_groovy_spaces_within_list_or_map = false +ij_groovy_spaces_within_method_call_parentheses = false +ij_groovy_spaces_within_method_parentheses = false +ij_groovy_spaces_within_parentheses = false +ij_groovy_spaces_within_switch_parentheses = false +ij_groovy_spaces_within_synchronized_parentheses = false +ij_groovy_spaces_within_try_parentheses = false +ij_groovy_spaces_within_tuple_expression = false +ij_groovy_spaces_within_while_parentheses = false +ij_groovy_special_else_if_treatment = true +ij_groovy_ternary_operation_wrap = off +ij_groovy_throws_keyword_wrap = off +ij_groovy_throws_list_wrap = off +ij_groovy_use_flying_geese_braces = false +ij_groovy_use_fq_class_names = false +ij_groovy_use_fq_class_names_in_javadoc = true +ij_groovy_use_relative_indents = false +ij_groovy_use_single_class_imports = true +ij_groovy_variable_annotation_wrap = off +ij_groovy_while_brace_force = never +ij_groovy_while_on_new_line = false +ij_groovy_wrap_long_lines = false + +[{*.gradle.kts,*.kt,*.kts,*.main.kts}] +ij_kotlin_align_in_columns_case_branch = true +ij_kotlin_align_multiline_binary_operation = false +ij_kotlin_align_multiline_extends_list = false +ij_kotlin_align_multiline_method_parentheses = false +ij_kotlin_align_multiline_parameters = true +ij_kotlin_align_multiline_parameters_in_calls = false +ij_kotlin_allow_trailing_comma = false +ij_kotlin_allow_trailing_comma_on_call_site = false +ij_kotlin_assignment_wrap = off +ij_kotlin_blank_lines_after_class_header = 0 +ij_kotlin_blank_lines_around_block_when_branches = 0 +ij_kotlin_blank_lines_before_declaration_with_comment_or_annotation_on_separate_line = 1 +ij_kotlin_block_comment_at_first_column = true +ij_kotlin_call_parameters_new_line_after_left_paren = false +ij_kotlin_call_parameters_right_paren_on_new_line = false +ij_kotlin_call_parameters_wrap = off +ij_kotlin_catch_on_new_line = false +ij_kotlin_class_annotation_wrap = off +ij_kotlin_code_style_defaults = KOTLIN_OFFICIAL +ij_kotlin_continuation_indent_for_chained_calls = true +ij_kotlin_continuation_indent_for_expression_bodies = true +ij_kotlin_continuation_indent_in_argument_lists = true +ij_kotlin_continuation_indent_in_elvis = true +ij_kotlin_continuation_indent_in_if_conditions = true +ij_kotlin_continuation_indent_in_parameter_lists = true +ij_kotlin_continuation_indent_in_supertype_lists = true +ij_kotlin_else_on_new_line = false +ij_kotlin_enum_constants_wrap = off +ij_kotlin_extends_list_wrap = off +ij_kotlin_field_annotation_wrap = normal +ij_kotlin_finally_on_new_line = false +ij_kotlin_if_rparen_on_new_line = false +ij_kotlin_import_nested_classes = false +ij_kotlin_imports_layout = *,java.**,javax.**,kotlin.**,^ +ij_kotlin_insert_whitespaces_in_simple_one_line_method = true +ij_kotlin_keep_blank_lines_before_right_brace = 0 +ij_kotlin_keep_blank_lines_in_code = 1 +ij_kotlin_keep_blank_lines_in_declarations = 1 +ij_kotlin_keep_first_column_comment = true +ij_kotlin_keep_indents_on_empty_lines = false +ij_kotlin_keep_line_breaks = true +ij_kotlin_lbrace_on_next_line = false +ij_kotlin_line_comment_add_space = false +ij_kotlin_line_comment_at_first_column = true +ij_kotlin_method_annotation_wrap = split_into_lines +ij_kotlin_method_call_chain_wrap = off +ij_kotlin_method_parameters_new_line_after_left_paren = false +ij_kotlin_method_parameters_right_paren_on_new_line = false +ij_kotlin_method_parameters_wrap = off +ij_kotlin_name_count_to_use_star_import = 2147483647 +ij_kotlin_name_count_to_use_star_import_for_members = 2147483647 +ij_kotlin_packages_to_use_import_on_demand = kotlinx.android.synthetic.** +ij_kotlin_parameter_annotation_wrap = off +ij_kotlin_space_after_comma = true +ij_kotlin_space_after_extend_colon = true +ij_kotlin_space_after_type_colon = true +ij_kotlin_space_before_catch_parentheses = true +ij_kotlin_space_before_comma = false +ij_kotlin_space_before_extend_colon = true +ij_kotlin_space_before_for_parentheses = true +ij_kotlin_space_before_if_parentheses = true +ij_kotlin_space_before_lambda_arrow = true +ij_kotlin_space_before_type_colon = false +ij_kotlin_space_before_when_parentheses = true +ij_kotlin_space_before_while_parentheses = true +ij_kotlin_spaces_around_additive_operators = true +ij_kotlin_spaces_around_assignment_operators = true +ij_kotlin_spaces_around_equality_operators = true +ij_kotlin_spaces_around_function_type_arrow = true +ij_kotlin_spaces_around_logical_operators = true +ij_kotlin_spaces_around_multiplicative_operators = true +ij_kotlin_spaces_around_range = false +ij_kotlin_spaces_around_relational_operators = true +ij_kotlin_spaces_around_unary_operator = false +ij_kotlin_spaces_around_when_arrow = true +ij_kotlin_use_custom_formatting_for_modifiers = true +ij_kotlin_variable_annotation_wrap = off +ij_kotlin_while_on_new_line = false +ij_kotlin_wrap_elvis_expressions = 1 +ij_kotlin_wrap_expression_body_functions = 0 +ij_kotlin_wrap_first_method_in_call_chain = false + +[{*.har,*.json}] +indent_size = 2 +ij_json_keep_blank_lines_in_code = 0 +ij_json_keep_indents_on_empty_lines = false +ij_json_keep_line_breaks = true +ij_json_space_after_colon = true +ij_json_space_after_comma = true +ij_json_space_before_colon = true +ij_json_space_before_comma = false +ij_json_spaces_within_braces = false +ij_json_spaces_within_brackets = false +ij_json_wrap_long_lines = false + +[{*.htm,*.html,*.sht,*.shtm,*.shtml}] +ij_html_add_new_line_before_tags = body,div,p,form,h1,h2,h3 +ij_html_align_attributes = true +ij_html_align_text = false +ij_html_attribute_wrap = normal +ij_html_block_comment_at_first_column = true +ij_html_do_not_align_children_of_min_lines = 0 +ij_html_do_not_break_if_inline_tags = title,h1,h2,h3,h4,h5,h6,p +ij_html_do_not_indent_children_of_tags = html,body,thead,tbody,tfoot +ij_html_enforce_quotes = false +ij_html_inline_tags = a,abbr,acronym,b,basefont,bdo,big,br,cite,cite,code,dfn,em,font,i,img,input,kbd,label,q,s,samp,select,small,span,strike,strong,sub,sup,textarea,tt,u,var +ij_html_keep_blank_lines = 2 +ij_html_keep_indents_on_empty_lines = false +ij_html_keep_line_breaks = true +ij_html_keep_line_breaks_in_text = true +ij_html_keep_whitespaces = false +ij_html_keep_whitespaces_inside = span,pre,textarea +ij_html_line_comment_at_first_column = true +ij_html_new_line_after_last_attribute = never +ij_html_new_line_before_first_attribute = never +ij_html_quote_style = double +ij_html_remove_new_line_before_tags = br +ij_html_space_after_tag_name = false +ij_html_space_around_equality_in_attribute = false +ij_html_space_inside_empty_tag = false +ij_html_text_wrap = normal +ij_html_uniform_ident = false + +[{*.yaml,*.yml}] +indent_size = 2 +ij_yaml_align_values_properties = do_not_align +ij_yaml_autoinsert_sequence_marker = true +ij_yaml_block_mapping_on_new_line = false +ij_yaml_indent_sequence_value = true +ij_yaml_keep_indents_on_empty_lines = false +ij_yaml_keep_line_breaks = true +ij_yaml_sequence_on_new_line = false +ij_yaml_space_before_colon = false +ij_yaml_spaces_within_braces = true +ij_yaml_spaces_within_brackets = true diff --git a/.github/ISSUE_TEMPLATE/release.yml b/.github/ISSUE_TEMPLATE/release.yml index 582998d492..c22b00e2e9 100644 --- a/.github/ISSUE_TEMPLATE/release.yml +++ b/.github/ISSUE_TEMPLATE/release.yml @@ -18,6 +18,7 @@ body: - [ ] Weblate sync, fix lint issue if any (in a dedicated PR) - [ ] Check the update of the store descriptions (using Google Translate if necessary) to ensure that the changes are acceptable to be published to the stores. + - [ ] While Weblate is locked, and after the PR from Weblate has been merged, handle all the TODOs in the main `strings.xml` file - [ ] Run the script `./tools/release/pushPlayStoreMetaData.sh`. You can check in the GooglePlay console the Activity log to check the effect. ### Do the release diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 7096e6bdb5..3940f2ca9e 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -17,7 +17,17 @@ ## Screenshots / GIFs -<!-- Only if UI have been changed --> +<!-- Only if UI have been changed +You can use a table like this to show screenshots comparison. +Uncomment this markdown table below and edit the last line `|||`: +|copy screenshot of before here|copy screenshot of after here| +--> + +<!-- +|Before|After| +|-|-| +||| + --> ## Tests diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 14b5112818..22b3a1727d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -37,7 +37,7 @@ jobs: - name: Assemble ${{ matrix.target }} debug apk run: ./gradlew assemble${{ matrix.target }}Debug $CI_GRADLE_ARG_PROPERTIES --stacktrace - name: Upload ${{ matrix.target }} debug APKs - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: vector-${{ matrix.target }}-debug path: | @@ -61,7 +61,7 @@ jobs: - name: Assemble GPlay unsigned apk run: ./gradlew clean assembleGplayRelease $CI_GRADLE_ARG_PROPERTIES --stacktrace - name: Upload Gplay unsigned APKs - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: vector-gplay-release-unsigned path: | diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index b875a57abe..84122095c6 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -26,7 +26,7 @@ jobs: steps: - uses: actions/checkout@v3 - uses: gradle/wrapper-validation-action@v1 - - uses: actions/setup-java@v2 + - uses: actions/setup-java@v3 with: distribution: 'adopt' java-version: 11 @@ -43,7 +43,7 @@ jobs: restore-keys: | ${{ runner.os }}-gradle- - name: Start synapse server - uses: michaelkaye/setup-matrix-synapse@v0.4.0 + uses: michaelkaye/setup-matrix-synapse@v1.0.1 with: uploadLogs: true httpPort: 8080 @@ -196,7 +196,7 @@ jobs: - `[org.matrix.android.sdk.PermalinkParserTest]`<br>${{ steps.get-comment-body-permalink.outputs.permalink }} edit-mode: replace - name: Upload Test Report Log - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: always() with: name: integrationtest-error-results @@ -230,12 +230,12 @@ jobs: restore-keys: | ${{ runner.os }}-gradle- - name: Start synapse server - uses: michaelkaye/setup-matrix-synapse@v0.4.0 + uses: michaelkaye/setup-matrix-synapse@v1.0.1 with: uploadLogs: true httpPort: 8080 disableRateLimiting: true - - uses: actions/setup-java@v2 + - uses: actions/setup-java@v3 with: distribution: 'adopt' java-version: '11' @@ -256,7 +256,7 @@ jobs: adb logcat >> emulator.log & ./gradlew $CI_GRADLE_ARG_PROPERTIES connectedGplayDebugAndroidTest -Pandroid.testInstrumentationRunnerArguments.class=im.vector.app.ui.UiAllScreensSanityTest || (adb pull storage/emulated/0/Pictures/failure_screenshots && exit 1 ) - name: Upload Test Report Log - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: always() with: name: uitest-error-results @@ -269,7 +269,7 @@ jobs: runs-on: macos-latest steps: - uses: actions/checkout@v3 - - uses: actions/setup-java@v2 + - uses: actions/setup-java@v3 with: distribution: 'adopt' java-version: '11' @@ -283,7 +283,7 @@ jobs: ${{ runner.os }}-gradle- - run: ./gradlew allCodeCoverageReport $CI_GRADLE_ARG_PROPERTIES - name: Upload Codecov data - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 if: always() with: name: codecov-xml @@ -298,7 +298,7 @@ jobs: - codecov-units steps: - uses: actions/checkout@v3 - - uses: actions/setup-java@v2 + - uses: actions/setup-java@v3 with: distribution: 'adopt' java-version: '11' diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 934c14629e..dee596980f 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -29,7 +29,7 @@ jobs: ./gradlew ktlintCheck --continue - name: Upload reports if: always() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: ktlinting-report path: | @@ -109,7 +109,7 @@ jobs: run: ./gradlew clean :vector:lint --stacktrace - name: Upload reports if: always() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: lint-report path: | @@ -142,7 +142,7 @@ jobs: run: ./gradlew clean lint${{ matrix.target }}Release --stacktrace - name: Upload ${{ matrix.target }} linting report if: always() - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: release-lint-report-${{ matrix.target }} path: | diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 98e5f588ca..3e8de8979c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -21,7 +21,7 @@ jobs: cancel-in-progress: true steps: - uses: actions/checkout@v3 - - uses: actions/setup-java@v2 + - uses: actions/setup-java@v3 with: distribution: 'adopt' java-version: 11 diff --git a/CHANGES.md b/CHANGES.md index 47b8c57041..4728994d77 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,65 @@ +Changes in Element v1.4.12 (2022-04-20) +======================================= + +Features ✨ +---------- + - Add a setting to be able to always appear offline ([#5582](https://github.com/vector-im/element-android/issues/5582)) + - Adds the ability for audio attachments to be played in the timeline ([#5586](https://github.com/vector-im/element-android/issues/5586)) + - Do not cancel the current incremental sync request and treatment when the app goes to background ([#5719](https://github.com/vector-im/element-android/issues/5719)) + - Improve user experience when home servers do not yet support threads ([#5761](https://github.com/vector-im/element-android/issues/5761)) + +Bugfixes 🐛 +---------- + - Added text next to spinner when loading information after user is clicked on space members screen ([#4305](https://github.com/vector-im/element-android/issues/4305)) + - The string `ftue_auth_carousel_workplace_body` was declared not translatable by mistake ([#5262](https://github.com/vector-im/element-android/issues/5262)) + - Fix some cases where the read marker line would not show up ([#5475](https://github.com/vector-im/element-android/issues/5475)) + - Fix sometimes read marker not properly updating ([#5481](https://github.com/vector-im/element-android/issues/5481)) + - Fix sometimes endless loading timeline ([#5554](https://github.com/vector-im/element-android/issues/5554)) + - Use member name instead of room name in DM creation item ([#5570](https://github.com/vector-im/element-android/issues/5570)) + - Align auto-reporting of decryption errors implementation with web client. ([#5596](https://github.com/vector-im/element-android/issues/5596)) + - Choosing "leave all rooms and spaces" while leaving Space won't cause leaving DMs in this Space anymore ([#5609](https://github.com/vector-im/element-android/issues/5609)) + - Fixes display name being changed when using /myroomnick ([#5618](https://github.com/vector-im/element-android/issues/5618)) + - Fix endless loading if the event from a permalink is not found ([#5659](https://github.com/vector-im/element-android/issues/5659)) + - Redacted events are no longer visible. ([#5707](https://github.com/vector-im/element-android/issues/5707)) + - Don't wrongly show non-space invites in the space panel. ([#5731](https://github.com/vector-im/element-android/issues/5731)) + - Fixes the onboarding confetti rendering behind the content instead of in-front ([#5735](https://github.com/vector-im/element-android/issues/5735)) + - Fixes crash when navigating the app whilst processing new room keys ([#5746](https://github.com/vector-im/element-android/issues/5746)) + - Fix sorting of uploads in encrypted rooms ([#5757](https://github.com/vector-im/element-android/issues/5757)) + - Fixing setting transfer title in call transfer. ([#5765](https://github.com/vector-im/element-android/issues/5765)) + - Changes destination after joining a space to Explore Space Rooms screen ([#5766](https://github.com/vector-im/element-android/issues/5766)) + - Unignoring a user will perform an initial sync ([#5767](https://github.com/vector-im/element-android/issues/5767)) + - Open a room by link: use the actual roomId instead of the alias ([#5786](https://github.com/vector-im/element-android/issues/5786)) + +In development 🚧 +---------------- + - FTUE - Adds a new homeserver selection screen when creating an account ([#2396](https://github.com/vector-im/element-android/issues/2396)) + - FTUE - Updates the Captcha and T&Cs registration screens UI style ([#5279](https://github.com/vector-im/element-android/issues/5279)) + - FTUE - Adds error handling within the server selection screen ([#5749](https://github.com/vector-im/element-android/issues/5749)) + - Live Location Sharing - Send location data ([#5697](https://github.com/vector-im/element-android/issues/5697)) + - Live Location Sharing - Show message on start of a live ([#5710](https://github.com/vector-im/element-android/issues/5710)) + - Live Location Sharing - Attach location data to beacon info state event ([#5711](https://github.com/vector-im/element-android/issues/5711)) + - Live Location Sharing - Update beacon info state event when sharing is ended ([#5758](https://github.com/vector-im/element-android/issues/5758)) + + +SDK API changes ⚠️ +------------------ + - Include original event in live decryption listeners and update sync status naming to InitialSyncProgressing for clarity. ([#5639](https://github.com/vector-im/element-android/issues/5639)) + - KeysBackupService.getCurrentVersion takes a new type `KeysBackupLastVersionResult` in the callback. ([#5703](https://github.com/vector-im/element-android/issues/5703)) + - A lot of classes which were exposed to the clients and were located in the package `org.matrix.android.sdk.internal` have been moved to the package `org.matrix.android.sdk.api`. + All the classes which are in the package `org.matrix.android.sdk.internal` should now be declared `internal`. + Some unused code and classes have been removed. ([#5744](https://github.com/vector-im/element-android/issues/5744)) + - Some data classes are now immutable, using `val` instead of `var` ([#5762](https://github.com/vector-im/element-android/issues/5762)) + +Other changes +------------- + - Upgrade konfetti lib from 1.3.2 to 2.0.2 ([#5079](https://github.com/vector-im/element-android/issues/5079)) + - Spaces feedback section is removed from left panel ([#5486](https://github.com/vector-im/element-android/issues/5486)) + - Reduce error logs ([#5703](https://github.com/vector-im/element-android/issues/5703)) + - Adds a complete editor config file for our current code style ([#5727](https://github.com/vector-im/element-android/issues/5727)) + - Updates the posthog dev environment url and api key ([#5732](https://github.com/vector-im/element-android/issues/5732)) + - Setup Dokka to be able to generate documentation of the SDK module. Run `./gradlew matrix-sdk-android:dokkaHtml` to do it. ([#5744](https://github.com/vector-im/element-android/issues/5744)) + + Changes in Element v1.4.11 (2022-04-07) ======================================= diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f3739be08d..053931cac5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -144,6 +144,8 @@ Instead, please comment the original string with: ```xml <!-- TODO TO BE REMOVED --> ``` +And add `tools:ignore="UnusedResources"` to the string, to let lint ignore that the string is not used. + The string will be removed during the next sync with Weblate. ### Accessibility diff --git a/build.gradle b/build.gradle index 352b82c457..1ff1da7427 100644 --- a/build.gradle +++ b/build.gradle @@ -22,6 +22,7 @@ buildscript { classpath 'com.google.android.gms:oss-licenses-plugin:0.10.5' classpath "com.likethesalad.android:stem-plugin:2.0.0" classpath 'org.owasp:dependency-check-gradle:7.0.4.1' + classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.6.20" // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files } @@ -105,6 +106,12 @@ allprojects { // display the corresponding rule verbose = true disabledRules = [ + // TODO: Re-enable these 4 rules after reformatting project + "indent", + "experimental:argument-list-wrapping", + "max-line-length", + "parameter-list-wrapping", + "spacing-between-declarations-with-comments", "no-multi-spaces", "experimental:spacing-between-declarations-with-annotations", diff --git a/coverage.gradle b/coverage.gradle index 96881dfff2..b62ce0b4a0 100644 --- a/coverage.gradle +++ b/coverage.gradle @@ -17,7 +17,7 @@ def initializeReport(report, projects, classExcludes) { projects.each { project -> switch (project) { case { project.plugins.hasPlugin("com.android.application") }: - androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/debug") + androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/gplayDebug") androidSourceDirs.add("${project.projectDir}/src/main/kotlin") androidSourceDirs.add("${project.projectDir}/src/main/java") break diff --git a/dependencies_groups.gradle b/dependencies_groups.gradle index ad016541d4..22cd48abc4 100644 --- a/dependencies_groups.gradle +++ b/dependencies_groups.gradle @@ -52,6 +52,7 @@ ext.groups = [ 'com.beust', 'com.davemorrissey.labs', 'com.dropbox.core', + 'com.soywiz.korlibs.korte', 'com.facebook.fbjni', 'com.facebook.fresco', 'com.facebook.infer.annotation', @@ -61,6 +62,9 @@ ext.groups = [ 'com.fasterxml', 'com.fasterxml.jackson', 'com.fasterxml.jackson.core', + 'com.fasterxml.jackson.dataformat', + 'com.fasterxml.jackson.module', + 'com.fasterxml.woodstox', 'com.gabrielittner.threetenbp', 'com.getkeepsafe.relinker', 'com.github.bumptech.glide', @@ -159,12 +163,14 @@ ext.groups = [ 'org.codehaus', 'org.codehaus.groovy', 'org.codehaus.mojo', + 'org.codehaus.woodstox', 'org.eclipse.ee4j', 'org.ec4j.core', 'org.glassfish.jaxb', 'org.hamcrest', 'org.jacoco', 'org.jetbrains', + 'org.jetbrains.dokka', 'org.jetbrains.intellij.deps', 'org.jetbrains.kotlin', 'org.jetbrains.kotlinx', @@ -210,4 +216,3 @@ ext.groups = [ ] ] ] - diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40104060.txt b/fastlane/metadata/android/cs-CZ/changelogs/40104060.txt new file mode 100644 index 0000000000..3eda022464 --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40104060.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Časová osa vláken je nyní živá a rychlejší. Opravy různých chyb a vylepšení stability. +Úplný seznam změn: https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40104070.txt b/fastlane/metadata/android/cs-CZ/changelogs/40104070.txt new file mode 100644 index 0000000000..cba2012c1c --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40104070.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Opravy různých chyb a vylepšení stability. +Úplný seznam změn: https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/cs-CZ/changelogs/40104080.txt b/fastlane/metadata/android/cs-CZ/changelogs/40104080.txt new file mode 100644 index 0000000000..61e7fd7940 --- /dev/null +++ b/fastlane/metadata/android/cs-CZ/changelogs/40104080.txt @@ -0,0 +1,2 @@ +Hlavní změny v této verzi: Časová osa vlákna je nyní živá a rychlejší. Opravy různých chyb a vylepšení stability. +Úplný seznam změn: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/en-US/changelogs/40104120.txt b/fastlane/metadata/android/en-US/changelogs/40104120.txt new file mode 100644 index 0000000000..ea188c101c --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/40104120.txt @@ -0,0 +1,2 @@ +Main changes in this version: Allows users to appear offline and adds an audio player for audio attachments +Full changelog: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/et/changelogs/40104060.txt b/fastlane/metadata/android/et/changelogs/40104060.txt new file mode 100644 index 0000000000..f506b617ed --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40104060.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: jutulõngad on nüüd kasutatavad ja toimivad kiiremini, lisaks pisiparandused ja stabiilsust parandavad kohendused. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/et/changelogs/40104070.txt b/fastlane/metadata/android/et/changelogs/40104070.txt new file mode 100644 index 0000000000..ea3582678d --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40104070.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: pisiparandused ja stabiilsust parandavad kohendused. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/et/changelogs/40104080.txt b/fastlane/metadata/android/et/changelogs/40104080.txt new file mode 100644 index 0000000000..a35fded9b6 --- /dev/null +++ b/fastlane/metadata/android/et/changelogs/40104080.txt @@ -0,0 +1,2 @@ +Põhilised muutused selles versioonis: jutulõngad on nüüd kasutatavad ja toimivad kiiremini, lisaks pisiparandused ja stabiilsust parandavad kohendused. +Kogu ingliskeelne muudatuste logi: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/fa/changelogs/40104060.txt b/fastlane/metadata/android/fa/changelogs/40104060.txt new file mode 100644 index 0000000000..5a1188b370 --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40104060.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: خط زمانی رشتهها اکنون زنده و سریعتر است. چندین رفع اشکال و بهبود پایداری. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/fa/changelogs/40104070.txt b/fastlane/metadata/android/fa/changelogs/40104070.txt new file mode 100644 index 0000000000..d35ded337b --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40104070.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: چندین رفع اشکال و بهبود پایداری. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/fa/changelogs/40104080.txt b/fastlane/metadata/android/fa/changelogs/40104080.txt new file mode 100644 index 0000000000..673a46a10d --- /dev/null +++ b/fastlane/metadata/android/fa/changelogs/40104080.txt @@ -0,0 +1,2 @@ +تغییرات عمده در این نگارش: خط زمانی رشتهها اکنون زنده و سریعتر است. چندین رفع اشکال و بهبود پایداری. +گزارش دگرگونی کامل: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/fr-FR/changelogs/40104040.txt b/fastlane/metadata/android/fr-FR/changelogs/40104040.txt new file mode 100644 index 0000000000..af2d7bb086 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40104040.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Mise-à-jour de l’interface de notification de rédaction en cours. Plusieurs corrections de bogues et d’améliorations de stabilité. +Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.4.4 diff --git a/fastlane/metadata/android/fr-FR/changelogs/40104060.txt b/fastlane/metadata/android/fr-FR/changelogs/40104060.txt new file mode 100644 index 0000000000..24e0fde3f3 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40104060.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Les fils de discussion sont officiellement disponibles, et plus rapides. Plusieurs corrections de bogues et d’améliorations de stabilité. +Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/fr-FR/changelogs/40104070.txt b/fastlane/metadata/android/fr-FR/changelogs/40104070.txt new file mode 100644 index 0000000000..3f9879d917 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40104070.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Plusieurs corrections de bogues et d’améliorations de stabilité. +Intégralité des changements : https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/fr-FR/changelogs/40104080.txt b/fastlane/metadata/android/fr-FR/changelogs/40104080.txt new file mode 100644 index 0000000000..84f92c18e2 --- /dev/null +++ b/fastlane/metadata/android/fr-FR/changelogs/40104080.txt @@ -0,0 +1,2 @@ +Principaux changements pour cette version : Les fils de discussion sont officiellement disponibles, et plus rapides. Plusieurs corrections de bogues et d’améliorations de stabilité. +Intégralité des changements : https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/hu-HU/changelogs/40104040.txt b/fastlane/metadata/android/hu-HU/changelogs/40104040.txt new file mode 100644 index 0000000000..60ec5256aa --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40104040.txt @@ -0,0 +1,2 @@ +Fő változás ebben a verzióban: Gépelés visszajelzési frissítések a felületen. További hibajavítások egy stabilitást növelő fejlesztések. +Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.4.4 diff --git a/fastlane/metadata/android/hu-HU/changelogs/40104060.txt b/fastlane/metadata/android/hu-HU/changelogs/40104060.txt new file mode 100644 index 0000000000..a3f4b89d92 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40104060.txt @@ -0,0 +1,2 @@ +Fő változás ebben a verzióban: Megjelentek az üzenetszálak az idővonalon és gyorsak. További hibajavítások és stabilitási fejlesztések. +Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/hu-HU/changelogs/40104070.txt b/fastlane/metadata/android/hu-HU/changelogs/40104070.txt new file mode 100644 index 0000000000..0f969fb577 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40104070.txt @@ -0,0 +1,2 @@ +Fő változás ebben a verzióban: Hibajavítások és stabilizációs fejlesztések. +Teljes változásnapló: https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/hu-HU/changelogs/40104080.txt b/fastlane/metadata/android/hu-HU/changelogs/40104080.txt new file mode 100644 index 0000000000..c29b20c216 --- /dev/null +++ b/fastlane/metadata/android/hu-HU/changelogs/40104080.txt @@ -0,0 +1,2 @@ +Fő változás ebben a verzióban: Megjelentek az üzenetszálak az idővonalon és gyorsak. További hibajavítások és stabilitási fejlesztések. +Teljes változásnapló: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/id/changelogs/40104060.txt b/fastlane/metadata/android/id/changelogs/40104060.txt new file mode 100644 index 0000000000..3b4ce82497 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40104060.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Linimasa utasan sekarang langsung dan lebih cepat. Banyak perbaikan kutu dan perbaikan stabilitas. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/id/changelogs/40104070.txt b/fastlane/metadata/android/id/changelogs/40104070.txt new file mode 100644 index 0000000000..39daf31eb6 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40104070.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Banyak perbaikan kutu dan perbaikan stabilitas. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/id/changelogs/40104080.txt b/fastlane/metadata/android/id/changelogs/40104080.txt new file mode 100644 index 0000000000..0a5ae82096 --- /dev/null +++ b/fastlane/metadata/android/id/changelogs/40104080.txt @@ -0,0 +1,2 @@ +Perubahan utama dalam versi ini: Linimasa utasan sekarang langsung dan lebih cepat. Banyak perbaikan kutu dan perbaikan stabilitas. +Catatan perubahan lanjutan: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/it-IT/changelogs/40104060.txt b/fastlane/metadata/android/it-IT/changelogs/40104060.txt new file mode 100644 index 0000000000..c9ea8af2cc --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40104060.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: la linea temporale per argomenti è ora attiva e più veloce. Varie correzioni e miglioramenti. +Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/it-IT/changelogs/40104070.txt b/fastlane/metadata/android/it-IT/changelogs/40104070.txt new file mode 100644 index 0000000000..2dfd415920 --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40104070.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: varie correzioni di errori e miglioramenti della stabilità. +Cronologia completa: https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/it-IT/changelogs/40104080.txt b/fastlane/metadata/android/it-IT/changelogs/40104080.txt new file mode 100644 index 0000000000..8427e3d3fe --- /dev/null +++ b/fastlane/metadata/android/it-IT/changelogs/40104080.txt @@ -0,0 +1,2 @@ +Modifiche principali in questa versione: la linea temporale per argomenti è ora attiva e più veloce. Varie correzioni e miglioramenti. +Cronologia completa: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103060.txt b/fastlane/metadata/android/pl-PL/changelogs/40103060.txt new file mode 100644 index 0000000000..9dc1e9e297 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103060.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Dodanie obsługi obecności, dla pokoju wiadomości bezpośrednich (uwaga: obecność jest wyłączona na matrix.org). Dodano ponownie obsługę Android Auto. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.6 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103070.txt b/fastlane/metadata/android/pl-PL/changelogs/40103070.txt index 2cb20a9570..08d9d2193e 100644 --- a/fastlane/metadata/android/pl-PL/changelogs/40103070.txt +++ b/fastlane/metadata/android/pl-PL/changelogs/40103070.txt @@ -1,2 +1,2 @@ -Główne zmiany w tej wersji: Poprawki błędów dotyczące głównie powiadomień -Pełny changelog: https://github.com/vector-im/element-android/releases/tag/v1.3.7 +Główne zmiany w tej wersji: Poprawki błędów dotyczące głównie powiadomień. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.7-RC2 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103080.txt b/fastlane/metadata/android/pl-PL/changelogs/40103080.txt new file mode 100644 index 0000000000..c850479f59 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103080.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Poprawki błędów! +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.8 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103090.txt b/fastlane/metadata/android/pl-PL/changelogs/40103090.txt new file mode 100644 index 0000000000..13e1aed51e --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103090.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Dodano obsługę wersji roboczej wiadomości głosowych. Wiele poprawek! +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.9 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103100.txt b/fastlane/metadata/android/pl-PL/changelogs/40103100.txt new file mode 100644 index 0000000000..406f07f70f --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103100.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Dodano obsługę ankiet (w laboratoriach). Nowy projekt podglądu adresu URL. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.10 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103110.txt b/fastlane/metadata/android/pl-PL/changelogs/40103110.txt new file mode 100644 index 0000000000..f9b38673c7 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103110.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Poprawki błędów! +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.11 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103120.txt b/fastlane/metadata/android/pl-PL/changelogs/40103120.txt new file mode 100644 index 0000000000..db6c1c86bd --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103120.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Poprawki błędów! +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.12 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103130.txt b/fastlane/metadata/android/pl-PL/changelogs/40103130.txt new file mode 100644 index 0000000000..affd085177 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103130.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Pierwsza zmiana na ekranach rejestracji, w tym możliwość włączenia Analytics. Dodano obsługę dla wydarzeń z dodatkiem matematyki w laboratoriach. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.13 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103140.txt b/fastlane/metadata/android/pl-PL/changelogs/40103140.txt new file mode 100644 index 0000000000..0727d3b4ff --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103140.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Pierwsza zmiana na ekranach rejestracji, w tym możliwość włączenia Analytics. Dodano obsługę dla wydarzeń z dodatkiem matematyki w laboratoriach. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.14 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103150.txt b/fastlane/metadata/android/pl-PL/changelogs/40103150.txt new file mode 100644 index 0000000000..48d6d0feb3 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103150.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Pierwsza zmiana na ekranach rejestracji, w tym możliwość włączenia Analytics. Dodano obsługę dla wydarzeń z dodatkiem matematyki w laboratoriach. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.15 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103160.txt b/fastlane/metadata/android/pl-PL/changelogs/40103160.txt new file mode 100644 index 0000000000..df66e3042a --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103160.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: wyślij swoją lokalizację do dowolnego pokoju. Edytuj ankietę. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.16 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103170.txt b/fastlane/metadata/android/pl-PL/changelogs/40103170.txt new file mode 100644 index 0000000000..77d40898a6 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103170.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: wyślij swoją lokalizację do dowolnego pokoju. Edytuj ankietę. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.17 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40103180.txt b/fastlane/metadata/android/pl-PL/changelogs/40103180.txt new file mode 100644 index 0000000000..c0f671a58e --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40103180.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: wyślij swoją lokalizację do dowolnego pokoju. Edytuj ankietę. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.3.18 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40104000.txt b/fastlane/metadata/android/pl-PL/changelogs/40104000.txt new file mode 100644 index 0000000000..f9f4c80cf9 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40104000.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Wstępna implementacja komunikatów wątków. Bąbelki wiadomości. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.4.0 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40104020.txt b/fastlane/metadata/android/pl-PL/changelogs/40104020.txt new file mode 100644 index 0000000000..190427d548 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40104020.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: dodanie obsługi @room i nieujawnionych ankiet, i wiele innych drobnych zmian. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.4.2 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40104040.txt b/fastlane/metadata/android/pl-PL/changelogs/40104040.txt new file mode 100644 index 0000000000..9894e54c03 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40104040.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: aktualizacje interfejsu użytkownika wskaźnika pisania. Różne poprawki błędów i ulepszenia stabilności. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.4.4 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40104060.txt b/fastlane/metadata/android/pl-PL/changelogs/40104060.txt new file mode 100644 index 0000000000..216842ada0 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40104060.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Oś czasu wątku jest teraz aktywna i szybsza. Różne poprawki błędów i ulepszenia stabilności. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40104070.txt b/fastlane/metadata/android/pl-PL/changelogs/40104070.txt new file mode 100644 index 0000000000..91c13d3d79 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40104070.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Różne poprawki błędów i ulepszenia stabilności. +Pełna lista zmian: https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/pl-PL/changelogs/40104080.txt b/fastlane/metadata/android/pl-PL/changelogs/40104080.txt new file mode 100644 index 0000000000..5286f40de5 --- /dev/null +++ b/fastlane/metadata/android/pl-PL/changelogs/40104080.txt @@ -0,0 +1,2 @@ +Główne zmiany w tej wersji: Oś czasu wątku jest teraz aktywna i szybsza. Różne poprawki błędów i ulepszenia stabilności. +Pełna lista zmian: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/pt-BR/changelogs/40104060.txt b/fastlane/metadata/android/pt-BR/changelogs/40104060.txt new file mode 100644 index 0000000000..17d8225c0d --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40104060.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: Timeline de Thread estão agora ao vivo e mais rápidas. Vários consertos de bugs e melhorias de estabilidade. +Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/pt-BR/changelogs/40104070.txt b/fastlane/metadata/android/pt-BR/changelogs/40104070.txt new file mode 100644 index 0000000000..fad9bfe739 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40104070.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: Vários consertos de bugs e melhorias de estabilidade. +Changelog completo: https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/pt-BR/changelogs/40104080.txt b/fastlane/metadata/android/pt-BR/changelogs/40104080.txt new file mode 100644 index 0000000000..ca2b54f2f2 --- /dev/null +++ b/fastlane/metadata/android/pt-BR/changelogs/40104080.txt @@ -0,0 +1,2 @@ +Principais mudanças nesta versão: Timeline de Thread estão agora ao vivo e mais rápidas. Vários consertos de bugs e melhorias de estabilidade. +Changelog completo: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/sk/changelogs/40104060.txt b/fastlane/metadata/android/sk/changelogs/40104060.txt new file mode 100644 index 0000000000..53e192fe7c --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40104060.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Vlákna na časovej osi sú teraz živé a rýchlejšie. Rôzne opravy chýb a vylepšenia stability. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/sk/changelogs/40104070.txt b/fastlane/metadata/android/sk/changelogs/40104070.txt new file mode 100644 index 0000000000..1e056cf32f --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40104070.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Rôzne opravy chýb a vylepšenia stability. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/sk/changelogs/40104080.txt b/fastlane/metadata/android/sk/changelogs/40104080.txt new file mode 100644 index 0000000000..7f42250fb9 --- /dev/null +++ b/fastlane/metadata/android/sk/changelogs/40104080.txt @@ -0,0 +1,2 @@ +Hlavné zmeny v tejto verzii: Vlákna na časovej osi sú teraz živé a rýchlejšie. Rôzne opravy chýb a vylepšenia stability. +Úplný zoznam zmien: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/sq/changelogs/40104060.txt b/fastlane/metadata/android/sq/changelogs/40104060.txt new file mode 100644 index 0000000000..48cbd2150c --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40104060.txt @@ -0,0 +1,2 @@ +Ndryshimet kryesore në këtë version: Vijat kohore të rrjedhave tani janë në punë dhe më të shpejta. Ndreqje të metash të ndryshme dhe përmirësime qëndrueshmërie. +Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/sq/changelogs/40104070.txt b/fastlane/metadata/android/sq/changelogs/40104070.txt new file mode 100644 index 0000000000..ad487c57ee --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40104070.txt @@ -0,0 +1,2 @@ +Ndryshimet kryesore në këtë version: Ndreqje të metash të ndryshme dhe përmirësime qëndrueshmërie. +Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/sq/changelogs/40104080.txt b/fastlane/metadata/android/sq/changelogs/40104080.txt new file mode 100644 index 0000000000..49156d0c96 --- /dev/null +++ b/fastlane/metadata/android/sq/changelogs/40104080.txt @@ -0,0 +1,2 @@ +Ndryshimet kryesore në këtë version: Vijat kohore të rrjedhave tani janë në punë dhe më të shpejta. Ndreqje të metash të ndryshme dhe përmirësime qëndrueshmërie. +Regjistër i plotë ndryshimesh: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/sv-SE/changelogs/40104060.txt b/fastlane/metadata/android/sv-SE/changelogs/40104060.txt new file mode 100644 index 0000000000..16a49fa3bc --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40104060.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: Trådtidslinje är nu live och snabbare. Diverse buggfixar och stabilitetsförbättringar. +Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/sv-SE/changelogs/40104070.txt b/fastlane/metadata/android/sv-SE/changelogs/40104070.txt new file mode 100644 index 0000000000..01f79e85d6 --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40104070.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: Diverse buggfixar och stabilitetsförbättringar. +Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/sv-SE/changelogs/40104080.txt b/fastlane/metadata/android/sv-SE/changelogs/40104080.txt new file mode 100644 index 0000000000..2ac7df2cda --- /dev/null +++ b/fastlane/metadata/android/sv-SE/changelogs/40104080.txt @@ -0,0 +1,2 @@ +Huvudsakliga ändringar i den här versionen: Trådtidslinje är nu live och snabbare. Diverse buggfixar och stabilitetsförbättringar. +Full ändringslogg: https://github.com/vector-im/element-android/releases/tag/v1.4.8 diff --git a/fastlane/metadata/android/uk/changelogs/40104060.txt b/fastlane/metadata/android/uk/changelogs/40104060.txt new file mode 100644 index 0000000000..28f051724a --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40104060.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: Хронологія тредів працює наживо і швидше. Усунуто різні вади й поліпшено стабільність. +Вичерпний перелік змін: https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/uk/changelogs/40104070.txt b/fastlane/metadata/android/uk/changelogs/40104070.txt new file mode 100644 index 0000000000..dff28b7825 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40104070.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: Усунуто різні вади й поліпшено стабільність. +Вичерпний перелік змін: https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/uk/changelogs/40104080.txt b/fastlane/metadata/android/uk/changelogs/40104080.txt new file mode 100644 index 0000000000..e5f7e7b271 --- /dev/null +++ b/fastlane/metadata/android/uk/changelogs/40104080.txt @@ -0,0 +1,2 @@ +Основні зміни в цій версії: Хронологія тредів працює наживо і швидше. Усунуто різні вади й поліпшено стабільність. +Вичерпний перелік змін: https://github.com/vector-im/element-android/releases diff --git a/fastlane/metadata/android/zh-TW/changelogs/40104060.txt b/fastlane/metadata/android/zh-TW/changelogs/40104060.txt new file mode 100644 index 0000000000..316fad3363 --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40104060.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:討論串時間軸現已更新,而且更快了。多個臭蟲修復與穩定性改善。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.4.6 diff --git a/fastlane/metadata/android/zh-TW/changelogs/40104070.txt b/fastlane/metadata/android/zh-TW/changelogs/40104070.txt new file mode 100644 index 0000000000..2cd9da666e --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40104070.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:多個臭蟲修復與穩定性改善。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases/tag/v1.4.7 diff --git a/fastlane/metadata/android/zh-TW/changelogs/40104080.txt b/fastlane/metadata/android/zh-TW/changelogs/40104080.txt new file mode 100644 index 0000000000..c036aa7d56 --- /dev/null +++ b/fastlane/metadata/android/zh-TW/changelogs/40104080.txt @@ -0,0 +1,2 @@ +此版本中的主要變動:討論串時間軸現已更新,而且更快了。多個臭蟲修復與穩定性改善。 +完整的變更紀錄:https://github.com/vector-im/element-android/releases diff --git a/library/core-utils/src/main/java/im/vector/lib/core/utils/flow/TimingOperators.kt b/library/core-utils/src/main/java/im/vector/lib/core/utils/flow/TimingOperators.kt index 065c19c17a..2efb439ace 100644 --- a/library/core-utils/src/main/java/im/vector/lib/core/utils/flow/TimingOperators.kt +++ b/library/core-utils/src/main/java/im/vector/lib/core/utils/flow/TimingOperators.kt @@ -25,7 +25,6 @@ import kotlinx.coroutines.channels.produce import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.consumeAsFlow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.isActive diff --git a/library/diff-match-patch/src/main/java/name/fraser/neil/plaintext/diff_match_patch.java b/library/diff-match-patch/src/main/java/name/fraser/neil/plaintext/diff_match_patch.java index 9d07867de5..484fb38b48 100644 --- a/library/diff-match-patch/src/main/java/name/fraser/neil/plaintext/diff_match_patch.java +++ b/library/diff-match-patch/src/main/java/name/fraser/neil/plaintext/diff_match_patch.java @@ -21,7 +21,15 @@ package name.fraser.neil.plaintext; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; import java.net.URLEncoder; -import java.util.*; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Deque; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; diff --git a/library/ui-styles/src/main/res/color/checkbox_tint_selector.xml b/library/ui-styles/src/main/res/color/checkbox_tint_selector.xml new file mode 100644 index 0000000000..67e2e68570 --- /dev/null +++ b/library/ui-styles/src/main/res/color/checkbox_tint_selector.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:color="?vctr_content_tertiary" android:state_checked="false" /> + <item android:color="?colorPrimary" android:state_checked="true" /> +</selector> \ No newline at end of file diff --git a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowExt.kt b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowExt.kt index 72493325c3..d21e898c1d 100644 --- a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowExt.kt +++ b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowExt.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright (c) 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt index 669e27edfd..18753f0705 100644 --- a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt +++ b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/FlowSession.kt @@ -23,6 +23,9 @@ import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.PrivateKeysInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo import org.matrix.android.sdk.api.session.group.GroupSummaryQueryParams import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.identity.ThreePid @@ -39,9 +42,6 @@ import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.api.session.widgets.model.Widget import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.toOptional -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo -import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo class FlowSession(private val session: Session) { diff --git a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/OptionalFlow.kt b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/OptionalFlow.kt index a9f062f379..42d84ed535 100644 --- a/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/OptionalFlow.kt +++ b/matrix-sdk-android-flow/src/main/java/org/matrix/android/sdk/flow/OptionalFlow.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 New Vector Ltd + * Copyright (c) 2021 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/matrix-sdk-android/build.gradle b/matrix-sdk-android/build.gradle index 788fdaff55..0cffa4148e 100644 --- a/matrix-sdk-android/build.gradle +++ b/matrix-sdk-android/build.gradle @@ -3,6 +3,7 @@ apply plugin: 'kotlin-android' apply plugin: 'kotlin-kapt' apply plugin: 'kotlin-parcelize' apply plugin: 'realm-android' +apply plugin: "org.jetbrains.dokka" buildscript { repositories { @@ -31,7 +32,7 @@ android { // that the app's state is completely cleared between tests. testInstrumentationRunnerArguments clearPackageData: 'true' - buildConfigField "String", "SDK_VERSION", "\"1.4.11\"" + buildConfigField "String", "SDK_VERSION", "\"1.4.12\"" buildConfigField "String", "GIT_SDK_REVISION", "\"${gitRevision()}\"" buildConfigField "String", "GIT_SDK_REVISION_UNIX_DATE", "\"${gitRevisionUnixDate()}\"" @@ -73,6 +74,10 @@ android { kotlinOptions { jvmTarget = "11" + freeCompilerArgs += [ + // Disabled for now, there are too many errors. Could be handled in another dedicated PR + // '-Xexplicit-api=strict', // or warning + ] } sourceSets { diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt index 71796192a8..e3ab1a4921 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/CryptoTestHelper.kt @@ -27,8 +27,12 @@ import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupAuthData +import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreationInfo import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.OutgoingSasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod @@ -42,10 +46,6 @@ import org.matrix.android.sdk.api.session.room.model.RoomSummary import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams import org.matrix.android.sdk.api.util.Optional -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo import java.util.UUID import kotlin.coroutines.Continuation import kotlin.coroutines.resume diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixComponent.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixComponent.kt index d0f0e23152..dc58339498 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixComponent.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/common/TestMatrixComponent.kt @@ -26,6 +26,7 @@ import org.matrix.android.sdk.internal.di.MatrixModule import org.matrix.android.sdk.internal.di.MatrixScope import org.matrix.android.sdk.internal.di.NetworkModule import org.matrix.android.sdk.internal.raw.RawModule +import org.matrix.android.sdk.internal.settings.SettingsModule import org.matrix.android.sdk.internal.util.system.SystemModule @Component(modules = [ @@ -34,6 +35,7 @@ import org.matrix.android.sdk.internal.util.system.SystemModule NetworkModule::class, AuthModule::class, RawModule::class, + SettingsModule::class, SystemModule::class ]) @MatrixScope diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt index aaf779212b..732f4f7dce 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/AttachmentEncryptionTest.kt @@ -25,10 +25,10 @@ import org.junit.FixMethodOrder import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters +import org.matrix.android.sdk.api.session.crypto.attachments.toElementToDecrypt +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileKey import org.matrix.android.sdk.internal.crypto.attachments.MXEncryptedAttachments -import org.matrix.android.sdk.internal.crypto.attachments.toElementToDecrypt -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileKey import java.io.ByteArrayOutputStream import java.io.InputStream diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt index 41ec69cdc5..3884683151 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/E2eeSanityTests.kt @@ -30,7 +30,13 @@ import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersion +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersionResult +import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreationInfo +import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.api.session.room.failure.JoinRoomFailure @@ -43,12 +49,6 @@ import org.matrix.android.sdk.common.CryptoTestHelper import org.matrix.android.sdk.common.SessionTestParams import org.matrix.android.sdk.common.TestConstants import org.matrix.android.sdk.common.TestMatrixCallback -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult -import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent @RunWith(JUnit4::class) @FixMethodOrder(MethodSorters.JVM) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt index 46c1dacf78..aa9f09314f 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/PreShareKeysTest.kt @@ -26,11 +26,11 @@ import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent +import org.matrix.android.sdk.api.session.events.model.content.RoomKeyContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent -import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent @RunWith(AndroidJUnit4::class) @FixMethodOrder(MethodSorters.JVM) @@ -90,7 +90,7 @@ class PreShareKeysTest : InstrumentedTest { // Just send a real message as test val sentEvent = testHelper.sendTextMessage(aliceSession.getRoom(e2eRoomID)!!, "Allo", 1).first() - assertEquals("Unexpected megolm session", megolmSessionId, sentEvent.root.content.toModel<EncryptedEventContent>()?.sessionId,) + assertEquals("Unexpected megolm session", megolmSessionId, sentEvent.root.content.toModel<EncryptedEventContent>()?.sessionId) testHelper.waitWithLatch { latch -> testHelper.retryPeriodicallyWithLatch(latch) { bobSession.getRoom(e2eRoomID)?.getTimelineEvent(sentEvent.eventId)?.root?.getClearType() == EventType.MESSAGE diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/UnwedgingTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/UnwedgingTest.kt index fb5d58b127..8346430530 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/UnwedgingTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/UnwedgingTest.kt @@ -32,6 +32,7 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.timeline.Timeline import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent @@ -40,7 +41,6 @@ import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper import org.matrix.android.sdk.common.TestConstants import org.matrix.android.sdk.internal.crypto.model.OlmSessionWrapper -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm import org.matrix.android.sdk.internal.crypto.store.db.serializeForRealm import org.matrix.olm.OlmSession diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/ExtensionsKtTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/ExtensionsKtTest.kt index 9fa7458ea7..936dc6a872 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/ExtensionsKtTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/ExtensionsKtTest.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.crypto.crosssigning import org.amshove.kluent.shouldBeNull import org.amshove.kluent.shouldBeTrue import org.junit.Test +import org.matrix.android.sdk.api.util.fromBase64 @Suppress("SpellCheckingInspection") class ExtensionsKtTest { diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt index a6e8f94c91..dc65cec187 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/crosssigning/XSigningTest.kt @@ -34,12 +34,14 @@ import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse +import org.matrix.android.sdk.api.session.crypto.crosssigning.isCrossSignedVerified +import org.matrix.android.sdk.api.session.crypto.crosssigning.isVerified +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper import org.matrix.android.sdk.common.SessionTestParams import org.matrix.android.sdk.common.TestConstants -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import kotlin.coroutines.Continuation import kotlin.coroutines.resume diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/encryption/EncryptionTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/encryption/EncryptionTest.kt index 060201d624..84c9487e03 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/encryption/EncryptionTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/encryption/EncryptionTest.kt @@ -24,7 +24,9 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.api.session.room.send.SendState @@ -33,8 +35,6 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.model.event.EncryptionEventContent import java.util.concurrent.CountDownLatch @RunWith(AndroidJUnit4::class) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt index cd20ab477c..5e271c6910 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/KeyShareTests.kt @@ -35,12 +35,20 @@ import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersion +import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreationInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.GossipingRequestState +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.api.session.crypto.model.OutgoingGossipingRequestState import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams @@ -48,14 +56,6 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.SessionTestParams import org.matrix.android.sdk.common.TestConstants -import org.matrix.android.sdk.internal.crypto.GossipingRequestState -import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestState -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent import kotlin.coroutines.Continuation import kotlin.coroutines.resume @@ -112,7 +112,7 @@ class KeyShareTests : InstrumentedTest { var outGoingRequestId: String? = null - commonTestHelper.waitWithLatch { latch -> + commonTestHelper.waitWithLatch { latch -> commonTestHelper.retryPeriodicallyWithLatch(latch) { aliceSession2.cryptoService().getOutgoingRoomKeyRequests() .filter { req -> diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt index e8f6eea460..55bb03278c 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/gossiping/WithHeldTests.kt @@ -30,14 +30,14 @@ import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent +import org.matrix.android.sdk.api.session.events.model.content.WithHeldCode import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper import org.matrix.android.sdk.common.MockOkHttpInterceptor import org.matrix.android.sdk.common.SessionTestParams import org.matrix.android.sdk.common.TestConstants -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent -import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode @RunWith(AndroidJUnit4::class) @FixMethodOrder(MethodSorters.JVM) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupScenarioData.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupScenarioData.kt index 864f3c12e4..45fdb9e1e3 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupScenarioData.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupScenarioData.kt @@ -24,10 +24,12 @@ import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrappe /** * Data class to store result of [KeysBackupTestHelper.createKeysBackupScenarioWithPassword] */ -data class KeysBackupScenarioData(val cryptoTestData: CryptoTestData, - val aliceKeys: List<OlmInboundGroupSessionWrapper2>, - val prepareKeysBackupDataResult: PrepareKeysBackupDataResult, - val aliceSession2: Session) { +internal data class KeysBackupScenarioData( + val cryptoTestData: CryptoTestData, + val aliceKeys: List<OlmInboundGroupSessionWrapper2>, + val prepareKeysBackupDataResult: PrepareKeysBackupDataResult, + val aliceSession2: Session +) { fun cleanUp(testHelper: CommonTestHelper) { cryptoTestData.cleanUp(testHelper) testHelper.signOutAndClose(aliceSession2) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt index 4c94566219..063c0c0ca3 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTest.kt @@ -29,21 +29,22 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.listeners.StepProgressListener +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupVersionTrust +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersion +import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreationInfo +import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult +import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper import org.matrix.android.sdk.common.TestConstants import org.matrix.android.sdk.common.TestMatrixCallback -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult -import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult import java.util.Collections import java.util.concurrent.CountDownLatch @@ -403,9 +404,9 @@ class KeysBackupTest : InstrumentedTest { assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) // - Retrieve the last version from the server - val keysVersionResult = testHelper.doSync<KeysVersionResult?> { + val keysVersionResult = testHelper.doSync<KeysBackupLastVersionResult> { testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(it) - } + }.toKeysVersionResult() // - It must be the same assertEquals(testData.prepareKeysBackupDataResult.version, keysVersionResult!!.version) @@ -463,9 +464,9 @@ class KeysBackupTest : InstrumentedTest { assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) // - Retrieve the last version from the server - val keysVersionResult = testHelper.doSync<KeysVersionResult?> { + val keysVersionResult = testHelper.doSync<KeysBackupLastVersionResult> { testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(it) - } + }.toKeysVersionResult() // - It must be the same assertEquals(testData.prepareKeysBackupDataResult.version, keysVersionResult!!.version) @@ -565,9 +566,9 @@ class KeysBackupTest : InstrumentedTest { assertTrue(testData.aliceSession2.cryptoService().keysBackupService().isEnabled) // - Retrieve the last version from the server - val keysVersionResult = testHelper.doSync<KeysVersionResult?> { + val keysVersionResult = testHelper.doSync<KeysBackupLastVersionResult> { testData.aliceSession2.cryptoService().keysBackupService().getCurrentVersion(it) - } + }.toKeysVersionResult() // - It must be the same assertEquals(testData.prepareKeysBackupDataResult.version, keysVersionResult!!.version) @@ -835,9 +836,9 @@ class KeysBackupTest : InstrumentedTest { keysBackupTestHelper.prepareAndCreateKeysBackupData(keysBackup) // Get key backup version from the homeserver - val keysVersionResult = testHelper.doSync<KeysVersionResult?> { + val keysVersionResult = testHelper.doSync<KeysBackupLastVersionResult> { keysBackup.getCurrentVersion(it) - } + }.toKeysVersionResult() // - Check the returned KeyBackupVersion is trusted val keysBackupVersionTrust = testHelper.doSync<KeysBackupVersionTrust> { diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt index 592b798bcc..ac83cb8882 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupTestHelper.kt @@ -22,16 +22,16 @@ import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersion +import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreationInfo import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper import org.matrix.android.sdk.common.assertDictEquals import org.matrix.android.sdk.common.assertListEquals import org.matrix.android.sdk.internal.crypto.MegolmSessionData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion import java.util.concurrent.CountDownLatch -class KeysBackupTestHelper( +internal class KeysBackupTestHelper( private val testHelper: CommonTestHelper, private val cryptoTestHelper: CryptoTestHelper) { diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/PrepareKeysBackupDataResult.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/PrepareKeysBackupDataResult.kt index 6aefe98f86..31bd3c9cce 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/PrepareKeysBackupDataResult.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/keysbackup/PrepareKeysBackupDataResult.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.internal.crypto.keysbackup -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo +import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreationInfo data class PrepareKeysBackupDataResult(val megolmBackupCreationInfo: MegolmBackupCreationInfo, val version: String) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt index 67f17727b1..d6baa4b1e0 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/ssss/QuadSTests.kt @@ -27,6 +27,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest +import org.matrix.android.sdk.api.crypto.SSSS_ALGORITHM_AES_HMAC_SHA2 import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent import org.matrix.android.sdk.api.session.securestorage.EncryptedSecretContent @@ -37,11 +38,10 @@ import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageError import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.api.util.toBase64NoPadding import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.SessionTestParams import org.matrix.android.sdk.common.TestConstants -import org.matrix.android.sdk.internal.crypto.SSSS_ALGORITHM_AES_HMAC_SHA2 -import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding import org.matrix.android.sdk.internal.crypto.secrets.DefaultSharedSecretStorageService @RunWith(AndroidJUnit4::class) diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt index 8cd725504d..14e659e2b6 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/crypto/verification/SASTest.kt @@ -31,6 +31,8 @@ import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.OutgoingSasVerificationTransaction @@ -44,8 +46,6 @@ import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.common.CommonTestHelper import org.matrix.android.sdk.common.CryptoTestHelper -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationStart import org.matrix.android.sdk.internal.crypto.model.rest.toValue diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/room/send/MarkdownParserTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/room/send/MarkdownParserTest.kt index 1e3512a9df..ef98ed22c7 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/room/send/MarkdownParserTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/room/send/MarkdownParserTest.kt @@ -27,6 +27,7 @@ import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest import org.matrix.android.sdk.api.MatrixConfiguration +import org.matrix.android.sdk.api.util.TextContent import org.matrix.android.sdk.common.TestRoomDisplayNameFallbackProvider import org.matrix.android.sdk.internal.session.displayname.DisplayNameResolver import org.matrix.android.sdk.internal.session.room.send.pills.MentionLinkSpecComparator diff --git a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtilsTest.kt b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtilsTest.kt index 7ee6caed0d..6bcd12742b 100644 --- a/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtilsTest.kt +++ b/matrix-sdk-android/src/androidTest/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtilsTest.kt @@ -24,8 +24,8 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.MethodSorters import org.matrix.android.sdk.InstrumentedTest -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding +import org.matrix.android.sdk.api.util.fromBase64 +import org.matrix.android.sdk.api.util.toBase64NoPadding import java.io.ByteArrayOutputStream import java.util.UUID diff --git a/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt b/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt index 34ed28d467..2661bd1f70 100644 --- a/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt +++ b/matrix-sdk-android/src/debug/java/org/matrix/android/sdk/internal/network/interceptors/FormattedJsonHttpLogger.kt @@ -23,7 +23,7 @@ import org.json.JSONException import org.json.JSONObject import timber.log.Timber -class FormattedJsonHttpLogger : HttpLoggingInterceptor.Logger { +internal class FormattedJsonHttpLogger : HttpLoggingInterceptor.Logger { companion object { private const val INDENT_SPACE = 2 diff --git a/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo001.kt b/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo001.kt index bd9a63b1c6..6ed9591bb7 100644 --- a/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo001.kt +++ b/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo001.kt @@ -4,7 +4,7 @@ import de.spiritcroc.android.sdk.internal.util.database.ScRealmMigrator import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields -class MigrateScSessionTo001(realm: DynamicRealm) : ScRealmMigrator(realm, 1) { +internal class MigrateScSessionTo001(realm: DynamicRealm) : ScRealmMigrator(realm, 1) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("RoomSummaryEntity") diff --git a/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo002.kt b/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo002.kt index bc4c690a51..7bf1dcf9c8 100644 --- a/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo002.kt +++ b/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo002.kt @@ -4,7 +4,7 @@ import de.spiritcroc.android.sdk.internal.util.database.ScRealmMigrator import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields -class MigrateScSessionTo002(realm: DynamicRealm) : ScRealmMigrator(realm, 2) { +internal class MigrateScSessionTo002(realm: DynamicRealm) : ScRealmMigrator(realm, 2) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("RoomSummaryEntity") diff --git a/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo003.kt b/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo003.kt index b3d2c871c3..3b70527469 100644 --- a/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo003.kt +++ b/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo003.kt @@ -4,7 +4,7 @@ import de.spiritcroc.android.sdk.internal.util.database.ScRealmMigrator import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields -class MigrateScSessionTo003(realm: DynamicRealm) : ScRealmMigrator(realm, 3) { +internal class MigrateScSessionTo003(realm: DynamicRealm) : ScRealmMigrator(realm, 3) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("RoomSummaryEntity") diff --git a/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo004.kt b/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo004.kt index 70222e3cd3..48630de9d2 100644 --- a/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo004.kt +++ b/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/database/migration/MigrateScSessionTo004.kt @@ -4,7 +4,7 @@ import de.spiritcroc.android.sdk.internal.util.database.ScRealmMigrator import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields -class MigrateScSessionTo004(realm: DynamicRealm) : ScRealmMigrator(realm, 4) { +internal class MigrateScSessionTo004(realm: DynamicRealm) : ScRealmMigrator(realm, 4) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("RoomSummaryEntity") diff --git a/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/util/database/ScRealmMigrator.kt b/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/util/database/ScRealmMigrator.kt index 3f0fa20053..e7f1a975d9 100644 --- a/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/util/database/ScRealmMigrator.kt +++ b/matrix-sdk-android/src/main/java/de/spiritcroc/android/sdk/internal/util/database/ScRealmMigrator.kt @@ -4,7 +4,7 @@ import io.realm.DynamicRealm import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber -abstract class ScRealmMigrator(private val realm: DynamicRealm, +internal abstract class ScRealmMigrator(private val realm: DynamicRealm, private val targetScSchemaVersion: Int): RealmMigrator(realm, 0) { override fun perform() { Timber.d("Migrate ${realm.configuration.realmFileName} to SC-version $targetScSchemaVersion") diff --git a/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/DisplayMaths.kt b/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/DisplayMaths.kt index b8ee36e724..3e83594ca3 100644 --- a/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/DisplayMaths.kt +++ b/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/DisplayMaths.kt @@ -17,7 +17,7 @@ package org.commonmark.ext.maths import org.commonmark.node.CustomBlock -class DisplayMaths(private val delimiter: DisplayDelimiter) : CustomBlock() { +internal class DisplayMaths(private val delimiter: DisplayDelimiter) : CustomBlock() { enum class DisplayDelimiter { DOUBLE_DOLLAR, SQUARE_BRACKET_ESCAPED diff --git a/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/InlineMaths.kt b/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/InlineMaths.kt index 962b1b8cbf..3fe8d15696 100644 --- a/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/InlineMaths.kt +++ b/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/InlineMaths.kt @@ -18,7 +18,7 @@ package org.commonmark.ext.maths import org.commonmark.node.CustomNode import org.commonmark.node.Delimited -class InlineMaths(private val delimiter: InlineDelimiter) : CustomNode(), Delimited { +internal class InlineMaths(private val delimiter: InlineDelimiter) : CustomNode(), Delimited { enum class InlineDelimiter { SINGLE_DOLLAR, ROUND_BRACKET_ESCAPED diff --git a/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/MathsExtension.kt b/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/MathsExtension.kt index 18c0fc4284..7a53253bd6 100644 --- a/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/MathsExtension.kt +++ b/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/MathsExtension.kt @@ -21,7 +21,7 @@ import org.commonmark.ext.maths.internal.MathsHtmlNodeRenderer import org.commonmark.parser.Parser import org.commonmark.renderer.html.HtmlRenderer -class MathsExtension private constructor() : Parser.ParserExtension, HtmlRenderer.HtmlRendererExtension { +internal class MathsExtension private constructor() : Parser.ParserExtension, HtmlRenderer.HtmlRendererExtension { override fun extend(parserBuilder: Parser.Builder) { parserBuilder.customDelimiterProcessor(DollarMathsDelimiterProcessor()) } diff --git a/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/internal/DollarMathsDelimiterProcessor.kt b/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/internal/DollarMathsDelimiterProcessor.kt index cfd03fa8f1..95ea1a1766 100644 --- a/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/internal/DollarMathsDelimiterProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/internal/DollarMathsDelimiterProcessor.kt @@ -21,7 +21,7 @@ import org.commonmark.node.Text import org.commonmark.parser.delimiter.DelimiterProcessor import org.commonmark.parser.delimiter.DelimiterRun -class DollarMathsDelimiterProcessor : DelimiterProcessor { +internal class DollarMathsDelimiterProcessor : DelimiterProcessor { override fun getOpeningCharacter() = '$' override fun getClosingCharacter() = '$' diff --git a/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/internal/MathsHtmlNodeRenderer.kt b/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/internal/MathsHtmlNodeRenderer.kt index 94652ed7ad..0efecbbe8a 100644 --- a/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/internal/MathsHtmlNodeRenderer.kt +++ b/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/internal/MathsHtmlNodeRenderer.kt @@ -22,7 +22,7 @@ import org.commonmark.renderer.html.HtmlNodeRendererContext import org.commonmark.renderer.html.HtmlWriter import java.util.Collections -class MathsHtmlNodeRenderer(private val context: HtmlNodeRendererContext) : MathsNodeRenderer() { +internal class MathsHtmlNodeRenderer(private val context: HtmlNodeRendererContext) : MathsNodeRenderer() { private val html: HtmlWriter = context.writer override fun render(node: Node) { val display = node.javaClass == DisplayMaths::class.java diff --git a/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/internal/MathsNodeRenderer.kt b/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/internal/MathsNodeRenderer.kt index 55cdc05c39..6924a9fb54 100644 --- a/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/internal/MathsNodeRenderer.kt +++ b/matrix-sdk-android/src/main/java/org/commonmark/ext/maths/internal/MathsNodeRenderer.kt @@ -19,9 +19,8 @@ import org.commonmark.ext.maths.DisplayMaths import org.commonmark.ext.maths.InlineMaths import org.commonmark.node.Node import org.commonmark.renderer.NodeRenderer -import java.util.HashSet -abstract class MathsNodeRenderer : NodeRenderer { +internal abstract class MathsNodeRenderer : NodeRenderer { override fun getNodeTypes(): Set<Class<out Node>> { val types: MutableSet<Class<out Node>> = HashSet() types.add(InlineMaths::class.java) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt index 5fedff53f0..e7b4b766ad 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/Matrix.kt @@ -29,6 +29,7 @@ import org.matrix.android.sdk.api.legacy.LegacySessionImporter import org.matrix.android.sdk.api.network.ApiInterceptorListener import org.matrix.android.sdk.api.network.ApiPath import org.matrix.android.sdk.api.raw.RawService +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.di.DaggerMatrixComponent import org.matrix.android.sdk.internal.network.ApiInterceptor @@ -56,6 +57,7 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo @Inject internal lateinit var homeServerHistoryService: HomeServerHistoryService @Inject internal lateinit var apiInterceptor: ApiInterceptor @Inject internal lateinit var matrixWorkerFactory: MatrixWorkerFactory + @Inject internal lateinit var lightweightSettingsStorage: LightweightSettingsStorage init { Monarchy.init(context) @@ -78,6 +80,8 @@ class Matrix private constructor(context: Context, matrixConfiguration: MatrixCo fun rawService() = rawService + fun lightweightSettingsStorage() = lightweightSettingsStorage + fun homeServerHistoryService() = homeServerHistoryService fun legacySessionImporter(): LegacySessionImporter { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt index c4bc289b75..f8472319fd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt @@ -61,10 +61,6 @@ data class MatrixConfiguration( * RoomDisplayNameFallbackProvider to provide default room display name. */ val roomDisplayNameFallbackProvider: RoomDisplayNameFallbackProvider, - /** - * True to enable presence information sync (if available). False to disable regardless of server setting. - */ - val presenceSyncEnabled: Boolean = true, /** * Thread messages default enable/disabled value */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/HomeServerHistoryService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/HomeServerHistoryService.kt index 77e33b8934..6850bdd444 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/HomeServerHistoryService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/HomeServerHistoryService.kt @@ -20,10 +20,19 @@ package org.matrix.android.sdk.api.auth * A simple service to remember homeservers you already connected to. */ interface HomeServerHistoryService { - + /** + * Get a list of stored homeserver urls. + */ fun getKnownServersUrls(): List<String> + /** + * Add a homeserver url to the list of stored homeserver urls. + * Will not be added again if already present in the list. + */ fun addHomeServerToHistory(url: String) + /** + * Delete the list of stored homeserver urls. + */ fun clearHistory() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/Credentials.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/Credentials.kt index 434e4a6e2e..317acccfb5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/Credentials.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/Credentials.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.api.auth.data import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.internal.util.md5 +import org.matrix.android.sdk.api.util.md5 /** * This data class hold credentials user data. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt index e87824d6a5..c2c1f043bb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt @@ -22,7 +22,7 @@ import okhttp3.CipherSuite import okhttp3.ConnectionSpec import okhttp3.TlsVersion import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig.Builder -import org.matrix.android.sdk.internal.network.ssl.Fingerprint +import org.matrix.android.sdk.api.network.ssl.Fingerprint import org.matrix.android.sdk.internal.util.ensureTrailingSlash /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/LocalizedFlowDataLoginTerms.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/LocalizedFlowDataLoginTerms.kt similarity index 79% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/LocalizedFlowDataLoginTerms.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/LocalizedFlowDataLoginTerms.kt index 5d119bb617..1e844a1d94 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/LocalizedFlowDataLoginTerms.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/LocalizedFlowDataLoginTerms.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.auth.registration +package org.matrix.android.sdk.api.auth.data import android.os.Parcelable import kotlinx.parcelize.Parcelize @@ -24,8 +24,8 @@ import kotlinx.parcelize.Parcelize */ @Parcelize data class LocalizedFlowDataLoginTerms( - var policyName: String? = null, - var version: String? = null, - var localizedUrl: String? = null, - var localizedName: String? = null + val policyName: String?, + val version: String?, + val localizedUrl: String?, + val localizedName: String? ) : Parcelable diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationFlowResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationFlowResponse.kt index ac740ddab7..0da9eb4b7e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationFlowResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/registration/RegistrationFlowResponse.kt @@ -19,8 +19,8 @@ package org.matrix.android.sdk.api.auth.registration import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.auth.data.LoginFlowTypes +import org.matrix.android.sdk.api.session.uia.InteractiveAuthenticationFlow import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.auth.data.InteractiveAuthenticationFlow @JsonClass(generateAdapter = true) data class RegistrationFlowResponse( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoConstants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/CryptoConstants.kt similarity index 96% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoConstants.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/CryptoConstants.kt index 96635b33d6..172cfa8360 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CryptoConstants.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/CryptoConstants.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto +package org.matrix.android.sdk.api.crypto /** * Matrix algorithm value for olm. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/extensions/MatrixSdkExtensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/extensions/MatrixSdkExtensions.kt index 1cdb6d49a5..f09e9bb340 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/extensions/MatrixSdkExtensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/extensions/MatrixSdkExtensions.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.api.extensions -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo /* ========================================================================================== * MXDeviceInfo diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt index 89b4a343dd..362ebcec26 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Extensions.kt @@ -22,29 +22,29 @@ import org.matrix.android.sdk.api.session.contentscanner.ContentScannerError import org.matrix.android.sdk.api.session.contentscanner.ScanFailure import org.matrix.android.sdk.internal.di.MoshiProvider import java.io.IOException +import java.net.UnknownHostException import javax.net.ssl.HttpsURLConnection -fun Throwable.is401() = - this is Failure.ServerError && - httpCode == HttpsURLConnection.HTTP_UNAUTHORIZED && /* 401 */ - error.code == MatrixError.M_UNAUTHORIZED +fun Throwable.is401() = this is Failure.ServerError && + httpCode == HttpsURLConnection.HTTP_UNAUTHORIZED && /* 401 */ + error.code == MatrixError.M_UNAUTHORIZED -fun Throwable.isTokenError() = - this is Failure.ServerError && - (error.code == MatrixError.M_UNKNOWN_TOKEN || - error.code == MatrixError.M_MISSING_TOKEN || - error.code == MatrixError.ORG_MATRIX_EXPIRED_ACCOUNT) +fun Throwable.is404() = this is Failure.ServerError && + httpCode == HttpsURLConnection.HTTP_NOT_FOUND && /* 404 */ + error.code == MatrixError.M_NOT_FOUND -fun Throwable.isLimitExceededError() = - this is Failure.ServerError && - httpCode == 429 && - error.code == MatrixError.M_LIMIT_EXCEEDED +fun Throwable.isTokenError() = this is Failure.ServerError && + (error.code == MatrixError.M_UNKNOWN_TOKEN || + error.code == MatrixError.M_MISSING_TOKEN || + error.code == MatrixError.ORG_MATRIX_EXPIRED_ACCOUNT) -fun Throwable.shouldBeRetried(): Boolean { - return this is Failure.NetworkConnection || - this is IOException || - this.isLimitExceededError() -} +fun Throwable.isLimitExceededError() = this is Failure.ServerError && + httpCode == 429 && + error.code == MatrixError.M_LIMIT_EXCEEDED + +fun Throwable.shouldBeRetried() = this is Failure.NetworkConnection || + this is IOException || + isLimitExceededError() /** * Get the retry delay in case of rate limit exceeded error, adding 100 ms, of defaultValue otherwise @@ -58,41 +58,33 @@ fun Throwable.getRetryDelay(defaultValue: Long): Long { ?: defaultValue } -fun Throwable.isUsernameInUse(): Boolean { - return this is Failure.ServerError && error.code == MatrixError.M_USER_IN_USE -} +fun Throwable.isUsernameInUse() = this is Failure.ServerError && + error.code == MatrixError.M_USER_IN_USE -fun Throwable.isInvalidUsername(): Boolean { - return this is Failure.ServerError && - error.code == MatrixError.M_INVALID_USERNAME -} +fun Throwable.isInvalidUsername() = this is Failure.ServerError && + error.code == MatrixError.M_INVALID_USERNAME -fun Throwable.isInvalidPassword(): Boolean { - return this is Failure.ServerError && - error.code == MatrixError.M_FORBIDDEN && - error.message == "Invalid password" -} +fun Throwable.isInvalidPassword() = this is Failure.ServerError && + error.code == MatrixError.M_FORBIDDEN && + error.message == "Invalid password" -fun Throwable.isRegistrationDisabled(): Boolean { - return this is Failure.ServerError && error.code == MatrixError.M_FORBIDDEN && - httpCode == HttpsURLConnection.HTTP_FORBIDDEN -} +fun Throwable.isRegistrationDisabled() = this is Failure.ServerError && + error.code == MatrixError.M_FORBIDDEN && + httpCode == HttpsURLConnection.HTTP_FORBIDDEN -fun Throwable.isWeakPassword(): Boolean { - return this is Failure.ServerError && error.code == MatrixError.M_WEAK_PASSWORD -} +fun Throwable.isWeakPassword() = this is Failure.ServerError && + error.code == MatrixError.M_WEAK_PASSWORD -fun Throwable.isLoginEmailUnknown(): Boolean { - return this is Failure.ServerError && - error.code == MatrixError.M_FORBIDDEN && - error.message.isEmpty() -} +fun Throwable.isLoginEmailUnknown() = this is Failure.ServerError && + error.code == MatrixError.M_FORBIDDEN && + error.message.isEmpty() -fun Throwable.isInvalidUIAAuth(): Boolean { - return this is Failure.ServerError && - error.code == MatrixError.M_FORBIDDEN && - error.flows != null -} +fun Throwable.isInvalidUIAAuth() = this is Failure.ServerError && + error.code == MatrixError.M_FORBIDDEN && + error.flows != null + +fun Throwable.isHomeserverUnavailable() = this is Failure.NetworkConnection && + this.ioException is UnknownHostException /** * Try to convert to a RegistrationFlowResponse. Return null in the cases it's not possible @@ -124,13 +116,11 @@ fun Throwable.toRegistrationFlowResponse(): RegistrationFlowResponse? { } } -fun Throwable.isRegistrationAvailabilityError(): Boolean { - return this is Failure.ServerError && - httpCode == HttpsURLConnection.HTTP_BAD_REQUEST && /* 400 */ - (error.code == MatrixError.M_USER_IN_USE || - error.code == MatrixError.M_INVALID_USERNAME || - error.code == MatrixError.M_EXCLUSIVE) -} +fun Throwable.isRegistrationAvailabilityError() = this is Failure.ServerError && + httpCode == HttpsURLConnection.HTTP_BAD_REQUEST && /* 400 */ + (error.code == MatrixError.M_USER_IN_USE || + error.code == MatrixError.M_INVALID_USERNAME || + error.code == MatrixError.M_EXCLUSIVE) /** * Try to convert to a ScanFailure. Return null in the cases it's not possible diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Failure.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Failure.kt index 8f1bbb6941..be139fd82b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Failure.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/Failure.kt @@ -17,8 +17,8 @@ package org.matrix.android.sdk.api.failure import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse +import org.matrix.android.sdk.api.network.ssl.Fingerprint import org.matrix.android.sdk.api.session.crypto.MXCryptoError -import org.matrix.android.sdk.internal.network.ssl.Fingerprint import java.io.IOException /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/GlobalError.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/GlobalError.kt index 50c84da02b..b5165b6687 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/GlobalError.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/GlobalError.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.api.failure -import org.matrix.android.sdk.internal.network.ssl.Fingerprint +import org.matrix.android.sdk.api.network.ssl.Fingerprint // This class will be sent to the bus sealed class GlobalError { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/MatrixError.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/MatrixError.kt index 1bc8636103..32e1aca17d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/MatrixError.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/failure/MatrixError.kt @@ -18,8 +18,8 @@ package org.matrix.android.sdk.api.failure import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.uia.InteractiveAuthenticationFlow import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.auth.data.InteractiveAuthenticationFlow /** * This data class holds the error defined by the matrix specifications. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/Fingerprint.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/network/ssl/Fingerprint.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/Fingerprint.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/network/ssl/Fingerprint.kt index b096bd6c87..93e93fd292 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/Fingerprint.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/network/ssl/Fingerprint.kt @@ -14,10 +14,11 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.network.ssl +package org.matrix.android.sdk.api.network.ssl import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.internal.network.ssl.CertUtil import java.security.cert.CertificateException import java.security.cert.X509Certificate diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/LiveEventListener.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/LiveEventListener.kt index 6fda65953a..b4b283c86a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/LiveEventListener.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/LiveEventListener.kt @@ -25,9 +25,9 @@ interface LiveEventListener { fun onPaginatedEvent(roomId: String, event: Event) - fun onEventDecrypted(eventId: String, roomId: String, clearEvent: JsonDict) + fun onEventDecrypted(event: Event, clearEvent: JsonDict) - fun onEventDecryptionError(eventId: String, roomId: String, throwable: Throwable) + fun onEventDecryptionError(event: Event, throwable: Throwable) fun onLiveToDeviceEvent(event: Event) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/ToDeviceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/ToDeviceService.kt index 45fd39fa95..d7afad5b6c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/ToDeviceService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/ToDeviceService.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.api.session +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.events.model.Content -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import java.util.UUID interface ToDeviceService { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentUrlResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentUrlResolver.kt index 3dd096e144..523d60359b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentUrlResolver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/content/ContentUrlResolver.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.api.session.content -import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt /** * This interface defines methods for accessing content from the current session. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/contentscanner/ContentScannerService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/contentscanner/ContentScannerService.kt index 1dd7bab01c..7a85a89058 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/contentscanner/ContentScannerService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/contentscanner/ContentScannerService.kt @@ -17,8 +17,8 @@ package org.matrix.android.sdk.api.session.contentscanner import androidx.lifecycle.LiveData +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt import org.matrix.android.sdk.api.util.Optional -import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt interface ContentScannerService { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt index a5b442dc4a..d6d1248de7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/CryptoService.kt @@ -23,25 +23,24 @@ import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListener +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DevicesListResponse +import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult +import org.matrix.android.sdk.api.session.crypto.model.IncomingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.MXDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.MXEncryptEventContentResult +import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.api.session.crypto.model.OutgoingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest -import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult -import org.matrix.android.sdk.internal.crypto.NewSessionListener -import org.matrix.android.sdk.internal.crypto.OutgoingRoomKeyRequest -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult -import org.matrix.android.sdk.internal.crypto.model.MXDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXEncryptEventContentResult -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody +import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent interface CryptoService { @@ -113,6 +112,7 @@ interface CryptoService { fun isRoomEncrypted(roomId: String): Boolean + // TODO This could be removed from this interface fun encryptEventContent(eventContent: Content, eventType: String, roomId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/MXCryptoError.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/MXCryptoError.kt index 4956278a10..5ff4b54b11 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/MXCryptoError.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/MXCryptoError.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.api.session.crypto -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.olm.OlmException /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/NewSessionListener.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/NewSessionListener.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/NewSessionListener.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/NewSessionListener.kt index 9b39a8ab25..73cbf5fb78 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/NewSessionListener.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/NewSessionListener.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto + +package org.matrix.android.sdk.api.session.crypto /** * This listener notifies on new Megolm sessions being created diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/ElementToDecrypt.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/attachments/ElementToDecrypt.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/ElementToDecrypt.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/attachments/ElementToDecrypt.kt index 3d00e178a0..de168ac6e5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/ElementToDecrypt.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/attachments/ElementToDecrypt.kt @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.attachments +package org.matrix.android.sdk.api.session.crypto.attachments import android.os.Parcelable import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo fun EncryptedFileInfo.toElementToDecrypt(): ElementToDecrypt? { // Check the validity of some fields diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt index 359e33cc2c..46b131f613 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CrossSigningService.kt @@ -20,9 +20,6 @@ import androidx.lifecycle.LiveData import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.util.Optional -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustResult -import org.matrix.android.sdk.internal.crypto.crosssigning.UserTrustResult -import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo interface CrossSigningService { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoCrossSigningKey.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CryptoCrossSigningKey.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoCrossSigningKey.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CryptoCrossSigningKey.kt index 606d2e3fc0..11996e673e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoCrossSigningKey.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/CryptoCrossSigningKey.kt @@ -14,9 +14,10 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model +package org.matrix.android.sdk.api.session.crypto.crosssigning -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.internal.crypto.model.CryptoInfo +import org.matrix.android.sdk.internal.crypto.model.CryptoInfoMapper import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo data class CryptoCrossSigningKey( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DeviceTrustLevel.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/DeviceTrustLevel.kt similarity index 87% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DeviceTrustLevel.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/DeviceTrustLevel.kt index fa0098e4a4..a0ab5b3b95 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DeviceTrustLevel.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/DeviceTrustLevel.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.crosssigning +package org.matrix.android.sdk.api.session.crypto.crosssigning data class DeviceTrustLevel( val crossSigningVerified: Boolean, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DeviceTrustResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/DeviceTrustResult.kt similarity index 88% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DeviceTrustResult.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/DeviceTrustResult.kt index 6e7c620a03..777d34221f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DeviceTrustResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/DeviceTrustResult.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,9 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.crosssigning - -import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo +package org.matrix.android.sdk.api.session.crypto.crosssigning sealed class DeviceTrustResult { data class Success(val level: DeviceTrustLevel) : DeviceTrustResult() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/MXCrossSigningInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/MXCrossSigningInfo.kt index 20ee68d228..9604decd62 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/MXCrossSigningInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/MXCrossSigningInfo.kt @@ -16,9 +16,6 @@ package org.matrix.android.sdk.api.session.crypto.crosssigning -import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey -import org.matrix.android.sdk.internal.crypto.model.KeyUsage - data class MXCrossSigningInfo( val userId: String, val crossSigningKeys: List<CryptoCrossSigningKey> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/PrivateKeysInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/PrivateKeysInfo.kt similarity index 92% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/PrivateKeysInfo.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/PrivateKeysInfo.kt index 04793f185a..f15d7dc598 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/PrivateKeysInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/PrivateKeysInfo.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.store +package org.matrix.android.sdk.api.session.crypto.crosssigning data class PrivateKeysInfo( val master: String? = null, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UserTrustResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/UserTrustResult.kt similarity index 83% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UserTrustResult.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/UserTrustResult.kt index 20e7ca09ab..7fc815cd20 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UserTrustResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/crosssigning/UserTrustResult.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,10 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.crosssigning - -import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo -import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey +package org.matrix.android.sdk.api.session.crypto.crosssigning sealed class UserTrustResult { object Success : UserTrustResult() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Try.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupLastVersionResult.kt similarity index 50% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Try.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupLastVersionResult.kt index 2ce0534b49..a7e985cea9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Try.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupLastVersionResult.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,27 +14,15 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.extensions +package org.matrix.android.sdk.api.session.crypto.keysbackup -import arrow.core.Failure -import arrow.core.Success -import arrow.core.Try -import arrow.core.TryOf -import arrow.core.fix - -inline fun <A> TryOf<A>.onError(f: (Throwable) -> Unit): Try<A> = fix() - .fold( - { - f(it) - Failure(it) - }, - { Success(it) } - ) - -/** - * Same as doOnNext for Observables - */ -inline fun <A> Try<A>.alsoDo(f: (A) -> Unit) = map { - f(it) - it +sealed interface KeysBackupLastVersionResult { + // No Keys backup found (404 error) + object NoKeysBackup : KeysBackupLastVersionResult + data class KeysBackup(val keysVersionResult: KeysVersionResult) : KeysBackupLastVersionResult +} + +fun KeysBackupLastVersionResult.toKeysVersionResult(): KeysVersionResult? = when (this) { + is KeysBackupLastVersionResult.KeysBackup -> keysVersionResult + KeysBackupLastVersionResult.NoKeysBackup -> null } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt index 4464427b90..9ff99f8dce 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupService.kt @@ -19,21 +19,16 @@ package org.matrix.android.sdk.api.session.crypto.keysbackup import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.listeners.StepProgressListener -import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult -import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult -import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo +import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult interface KeysBackupService { /** * Retrieve the current version of the backup from the homeserver * * It can be different than keysBackupVersion. - * @param callback onSuccess(null) will be called if there is no backup on the server + * @param callback Asynchronous callback */ - fun getCurrentVersion(callback: MatrixCallback<KeysVersionResult?>) + fun getCurrentVersion(callback: MatrixCallback<KeysBackupLastVersionResult>) /** * Create a new keys backup version and enable it, using the information return from [prepareKeysBackupVersion]. @@ -219,4 +214,9 @@ interface KeysBackupService { fun getKeyBackupRecoveryKeyInfo(): SavedKeyBackupKeyInfo? fun isValidRecoveryKeyForCurrentVersion(recoveryKey: String, callback: MatrixCallback<Boolean>) + + fun computePrivateKey(passphrase: String, + privateKeySalt: String, + privateKeyIterations: Int, + progressListener: ProgressListener): ByteArray } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeysBackupVersionTrust.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupVersionTrust.kt similarity index 83% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeysBackupVersionTrust.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupVersionTrust.kt index 497cb0eb49..c9a2d4e7a5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeysBackupVersionTrust.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupVersionTrust.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.keysbackup.model +package org.matrix.android.sdk.api.session.crypto.keysbackup /** * Data model for response to [KeysBackup.getKeysBackupTrust()]. @@ -24,10 +24,10 @@ data class KeysBackupVersionTrust( * Flag to indicate if the backup is trusted. * true if there is a signature that is valid & from a trusted device. */ - var usable: Boolean = false, + val usable: Boolean, /** * Signatures found in the backup version. */ - var signatures: MutableList<KeysBackupVersionTrustSignature> = ArrayList() + val signatures: List<KeysBackupVersionTrustSignature> = emptyList() ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeysBackupVersionTrustSignature.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupVersionTrustSignature.kt similarity index 53% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeysBackupVersionTrustSignature.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupVersionTrustSignature.kt index 1e3db28882..219a328cfd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeysBackupVersionTrustSignature.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysBackupVersionTrustSignature.kt @@ -14,28 +14,27 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.keysbackup.model +package org.matrix.android.sdk.api.session.crypto.keysbackup -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo /** * A signature in a `KeysBackupVersionTrust` object. */ -class KeysBackupVersionTrustSignature { +data class KeysBackupVersionTrustSignature( + /** + * The id of the device that signed the backup version. + */ + val deviceId: String?, - /** - * The id of the device that signed the backup version. - */ - var deviceId: String? = null + /** + * The device that signed the backup version. + * Can be null if the device is not known. + */ + val device: CryptoDeviceInfo?, - /** - * The device that signed the backup version. - * Can be null if the device is not known. - */ - var device: CryptoDeviceInfo? = null - - /** - * Flag to indicate the signature from this device is valid. - */ - var valid = false -} + /** + * Flag to indicate the signature from this device is valid. + */ + val valid: Boolean, +) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysVersion.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysVersion.kt similarity index 86% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysVersion.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysVersion.kt index 7a4c3415fc..1dbfe84dff 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysVersion.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysVersion.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.keysbackup.model.rest +package org.matrix.android.sdk.api.session.crypto.keysbackup import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysVersionResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysVersionResult.kt similarity index 91% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysVersionResult.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysVersionResult.kt index 485fd48a8c..f283a34e98 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysVersionResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/KeysVersionResult.kt @@ -14,11 +14,12 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.keysbackup.model.rest +package org.matrix.android.sdk.api.session.crypto.keysbackup import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysAlgorithmAndData @JsonClass(generateAdapter = true) data class KeysVersionResult( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/MegolmBackupAuthData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/MegolmBackupAuthData.kt similarity index 79% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/MegolmBackupAuthData.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/MegolmBackupAuthData.kt index 17c895762c..2a620af843 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/MegolmBackupAuthData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/MegolmBackupAuthData.kt @@ -14,11 +14,12 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.keysbackup.model +package org.matrix.android.sdk.api.session.crypto.keysbackup import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.internal.crypto.keysbackup.model.SignalableMegolmBackupAuthData import org.matrix.android.sdk.internal.di.MoshiProvider /** @@ -54,7 +55,7 @@ data class MegolmBackupAuthData( val signatures: Map<String, Map<String, String>>? = null ) { - fun toJsonDict(): JsonDict { + internal fun toJsonDict(): JsonDict { val moshi = MoshiProvider.providesMoshi() val adapter = moshi.adapter(Map::class.java) @@ -67,7 +68,7 @@ data class MegolmBackupAuthData( } } - fun signalableJSONDictionary(): JsonDict { + internal fun signalableJSONDictionary(): JsonDict { return SignalableMegolmBackupAuthData( publicKey = publicKey, privateKeySalt = privateKeySalt, @@ -76,20 +77,3 @@ data class MegolmBackupAuthData( .signalableJSONDictionary() } } - -internal data class SignalableMegolmBackupAuthData( - val publicKey: String, - val privateKeySalt: String? = null, - val privateKeyIterations: Int? = null -) { - fun signalableJSONDictionary(): JsonDict = HashMap<String, Any>().apply { - put("public_key", publicKey) - - privateKeySalt?.let { - put("private_key_salt", it) - } - privateKeyIterations?.let { - put("private_key_iterations", it) - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/MegolmBackupCreationInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/MegolmBackupCreationInfo.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/MegolmBackupCreationInfo.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/MegolmBackupCreationInfo.kt index c668e78a9e..0d708b8d73 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/MegolmBackupCreationInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/MegolmBackupCreationInfo.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.keysbackup.model +package org.matrix.android.sdk.api.session.crypto.keysbackup /** * Data retrieved from Olm library. algorithm and authData will be send to the homeserver, and recoveryKey will be displayed to the user diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/RecoveryKey.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/RecoveryKey.kt similarity index 93% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/RecoveryKey.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/RecoveryKey.kt index 44774fd5a6..85d6ef4365 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/RecoveryKey.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/RecoveryKey.kt @@ -14,8 +14,10 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.keysbackup.util +package org.matrix.android.sdk.api.session.crypto.keysbackup +import org.matrix.android.sdk.internal.crypto.keysbackup.util.base58decode +import org.matrix.android.sdk.internal.crypto.keysbackup.util.base58encode import kotlin.experimental.xor /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/SavedKeyBackupKeyInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/SavedKeyBackupKeyInfo.kt similarity index 92% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/SavedKeyBackupKeyInfo.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/SavedKeyBackupKeyInfo.kt index a48f4ecef5..7f90fea9af 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/SavedKeyBackupKeyInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keysbackup/SavedKeyBackupKeyInfo.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.store +package org.matrix.android.sdk.api.session.crypto.keysbackup data class SavedKeyBackupKeyInfo( val recoveryKey: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keyshare/GossipingRequestListener.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keyshare/GossipingRequestListener.kt index ba2d4ba3f6..3cd36c2ce8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keyshare/GossipingRequestListener.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/keyshare/GossipingRequestListener.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.api.session.crypto.keyshare -import org.matrix.android.sdk.internal.crypto.IncomingRequestCancellation -import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest -import org.matrix.android.sdk.internal.crypto.IncomingSecretShareRequest +import org.matrix.android.sdk.api.session.crypto.model.IncomingRequestCancellation +import org.matrix.android.sdk.api.session.crypto.model.IncomingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.IncomingSecretShareRequest /** * Room keys events listener diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/CryptoDeviceInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/CryptoDeviceInfo.kt new file mode 100644 index 0000000000..418b1e6ce3 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/CryptoDeviceInfo.kt @@ -0,0 +1,75 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.session.crypto.model + +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.internal.crypto.model.CryptoInfo + +data class CryptoDeviceInfo( + val deviceId: String, + override val userId: String, + val algorithms: List<String>? = null, + override val keys: Map<String, String>? = null, + override val signatures: Map<String, Map<String, String>>? = null, + val unsigned: UnsignedDeviceInfo? = null, + var trustLevel: DeviceTrustLevel? = null, + val isBlocked: Boolean = false, + val firstTimeSeenLocalTs: Long? = null +) : CryptoInfo { + + val isVerified: Boolean + get() = trustLevel?.isVerified() == true + + val isUnknown: Boolean + get() = trustLevel == null + + /** + * @return the fingerprint + */ + fun fingerprint(): String? { + return keys + ?.takeIf { deviceId.isNotBlank() } + ?.get("ed25519:$deviceId") + } + + /** + * @return the identity key + */ + fun identityKey(): String? { + return keys + ?.takeIf { deviceId.isNotBlank() } + ?.get("curve25519:$deviceId") + } + + /** + * @return the display name + */ + fun displayName(): String? { + return unsigned?.deviceDisplayName + } + + override fun signalableJSONDictionary(): Map<String, Any> { + val map = HashMap<String, Any>() + map["device_id"] = deviceId + map["user_id"] = userId + algorithms?.let { map["algorithms"] = it } + keys?.let { map["keys"] = it } + return map + } + + fun shortDebugString() = "$userId|$deviceId" +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DeviceInfo.kt similarity index 96% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceInfo.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DeviceInfo.kt index c5cd400342..221d0793d9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DeviceInfo.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest +package org.matrix.android.sdk.api.session.crypto.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DevicesListResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DevicesListResponse.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DevicesListResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DevicesListResponse.kt index eb325f332e..01f3321166 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DevicesListResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/DevicesListResponse.kt @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest + +package org.matrix.android.sdk.api.session.crypto.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/EncryptedFileInfo.kt similarity index 97% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileInfo.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/EncryptedFileInfo.kt index 4fc3adb42c..13ad1df476 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/EncryptedFileInfo.kt @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest + +package org.matrix.android.sdk.api.session.crypto.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileKey.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/EncryptedFileKey.kt similarity index 97% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileKey.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/EncryptedFileKey.kt index 71f266d7a5..859c6ac43f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedFileKey.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/EncryptedFileKey.kt @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest + +package org.matrix.android.sdk.api.session.crypto.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/ForwardedRoomKeyContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/ForwardedRoomKeyContent.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/ForwardedRoomKeyContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/ForwardedRoomKeyContent.kt index bbc24f0447..3df4ef7c9a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/ForwardedRoomKeyContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/ForwardedRoomKeyContent.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest + +package org.matrix.android.sdk.api.session.crypto.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/GossipingRequestState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/GossipingRequestState.kt similarity index 76% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/GossipingRequestState.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/GossipingRequestState.kt index e398cbfcaf..d9a6f4fcba 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/GossipingRequestState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/GossipingRequestState.kt @@ -14,12 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto - -enum class GossipRequestType { - KEY, - SECRET -} +package org.matrix.android.sdk.api.session.crypto.model enum class GossipingRequestState { NONE, @@ -34,13 +29,3 @@ enum class GossipingRequestState { CANCELLED_BY_REQUESTER, RE_REQUESTED } - -enum class OutgoingGossipingRequestState { - UNSENT, - SENDING, - SENT, - CANCELLING, - CANCELLED, - FAILED_TO_SEND, - FAILED_TO_CANCEL -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/GossipingToDeviceObject.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/GossipingToDeviceObject.kt similarity index 70% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/GossipingToDeviceObject.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/GossipingToDeviceObject.kt index e2ae9d1d6c..1922b2bcee 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/GossipingToDeviceObject.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/GossipingToDeviceObject.kt @@ -13,10 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest -import com.squareup.moshi.Json -import com.squareup.moshi.JsonClass +package org.matrix.android.sdk.api.session.crypto.model /** * Interface representing an room key action request @@ -35,10 +33,3 @@ interface GossipingToDeviceObject : SendToDeviceObject { const val ACTION_SHARE_CANCELLATION = "request_cancellation" } } - -@JsonClass(generateAdapter = true) -data class GossipingDefaultContent( - @Json(name = "action") override val action: String?, - @Json(name = "requesting_device_id") override val requestingDeviceId: String?, - @Json(name = "m.request_id") override val requestId: String? = null -) : GossipingToDeviceObject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/ImportRoomKeysResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/ImportRoomKeysResult.kt similarity index 76% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/ImportRoomKeysResult.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/ImportRoomKeysResult.kt index e9d2a1bcd8..b55f0e8747 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/ImportRoomKeysResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/ImportRoomKeysResult.kt @@ -14,7 +14,9 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model +package org.matrix.android.sdk.api.session.crypto.model -data class ImportRoomKeysResult(val totalNumberOfKeys: Int, - val successfullyNumberOfImportedKeys: Int) +data class ImportRoomKeysResult( + val totalNumberOfKeys: Int, + val successfullyNumberOfImportedKeys: Int +) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingRequestCancellation.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/IncomingRequestCancellation.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingRequestCancellation.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/IncomingRequestCancellation.kt index 181bc0c1b1..74ca7304f7 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingRequestCancellation.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/IncomingRequestCancellation.kt @@ -14,10 +14,11 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto +package org.matrix.android.sdk.api.session.crypto.model import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.internal.crypto.IncomingShareRequestCommon import org.matrix.android.sdk.internal.crypto.model.rest.ShareRequestCancellation /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingRoomKeyRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/IncomingRoomKeyRequest.kt similarity index 92% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingRoomKeyRequest.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/IncomingRoomKeyRequest.kt index babc6008a2..45b0926d89 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingRoomKeyRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/IncomingRoomKeyRequest.kt @@ -14,12 +14,11 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto +package org.matrix.android.sdk.api.session.crypto.model import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyShareRequest +import org.matrix.android.sdk.internal.crypto.IncomingShareRequestCommon /** * IncomingRoomKeyRequest class defines the incoming room keys request. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingSecretShareRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/IncomingSecretShareRequest.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingSecretShareRequest.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/IncomingSecretShareRequest.kt index d2ee69196c..5afffef1ae 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingSecretShareRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/IncomingSecretShareRequest.kt @@ -14,11 +14,11 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto +package org.matrix.android.sdk.api.session.crypto.model import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.internal.crypto.model.rest.SecretShareRequest +import org.matrix.android.sdk.internal.crypto.IncomingShareRequestCommon /** * IncomingSecretShareRequest class defines the incoming secret keys request. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXDeviceInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXDeviceInfo.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXDeviceInfo.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXDeviceInfo.kt index 68cc41005e..286ab2b7d5 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXDeviceInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXDeviceInfo.kt @@ -14,12 +14,11 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model +package org.matrix.android.sdk.api.session.crypto.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceKeys import java.io.Serializable @JsonClass(generateAdapter = true) @@ -144,19 +143,6 @@ data class MXDeviceInfo( return map } - /** - * @return a dictionary of the parameters - */ - fun toDeviceKeys(): DeviceKeys { - return DeviceKeys( - userId = userId, - deviceId = deviceId, - algorithms = algorithms!!, - keys = keys!!, - signatures = signatures!! - ) - } - override fun toString(): String { return "MXDeviceInfo $userId:$deviceId" } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXEncryptEventContentResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXEncryptEventContentResult.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXEncryptEventContentResult.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXEncryptEventContentResult.kt index 524bc80843..706e40a769 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXEncryptEventContentResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXEncryptEventContentResult.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model +package org.matrix.android.sdk.api.session.crypto.model import org.matrix.android.sdk.api.session.events.model.Content diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXEventDecryptionResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXEventDecryptionResult.kt similarity index 96% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXEventDecryptionResult.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXEventDecryptionResult.kt index c66c37574a..0a0ccc2db3 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXEventDecryptionResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXEventDecryptionResult.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto +package org.matrix.android.sdk.api.session.crypto.model import org.matrix.android.sdk.api.util.JsonDict @@ -22,7 +22,6 @@ import org.matrix.android.sdk.api.util.JsonDict * The result of a (successful) call to decryptEvent. */ data class MXEventDecryptionResult( - /** * The plaintext payload for the event (typically containing "type" and "content" fields). */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt new file mode 100755 index 0000000000..dc5567e908 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/MXUsersDevicesMap.kt @@ -0,0 +1,131 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.session.crypto.model + +class MXUsersDevicesMap<E> { + + // A map of maps (userId -> (deviceId -> Object)). + val map = HashMap<String /* userId */, HashMap<String /* deviceId */, E>>() + + /** + * @return the user Ids + */ + val userIds: List<String> + get() = map.keys.toList() + + val isEmpty: Boolean + get() = map.isEmpty() + + /** + * Provides the device ids list for a user id + * FIXME Should maybe return emptyList and not null, to avoid many !! in the code + * + * @param userId the user id + * @return the device ids list + */ + fun getUserDeviceIds(userId: String?): List<String>? { + return if (!userId.isNullOrBlank() && map.containsKey(userId)) { + map[userId]!!.keys.toList() + } else null + } + + /** + * Provides the object for a device id and a user Id + * + * @param deviceId the device id + * @param userId the object id + * @return the object + */ + fun getObject(userId: String?, deviceId: String?): E? { + return if (!userId.isNullOrBlank() && !deviceId.isNullOrBlank()) { + map[userId]?.get(deviceId) + } else null + } + + /** + * Set an object for a dedicated user Id and device Id + * + * @param userId the user Id + * @param deviceId the device id + * @param o the object to set + */ + fun setObject(userId: String?, deviceId: String?, o: E?) { + if (null != o && userId?.isNotBlank() == true && deviceId?.isNotBlank() == true) { + val devices = map.getOrPut(userId) { HashMap() } + devices[deviceId] = o + } + } + + /** + * Defines the objects map for a user Id + * + * @param objectsPerDevices the objects maps + * @param userId the user id + */ + fun setObjects(userId: String?, objectsPerDevices: Map<String, E>?) { + if (!userId.isNullOrBlank()) { + if (null == objectsPerDevices) { + map.remove(userId) + } else { + map[userId] = HashMap(objectsPerDevices) + } + } + } + + /** + * Removes objects for a dedicated user + * + * @param userId the user id. + */ + fun removeUserObjects(userId: String?) { + if (!userId.isNullOrBlank()) { + map.remove(userId) + } + } + + /** + * Clear the internal dictionary + */ + fun removeAllObjects() { + map.clear() + } + + /** + * Add entries from another MXUsersDevicesMap + * + * @param other the other one + */ + fun addEntriesFromMap(other: MXUsersDevicesMap<E>?) { + if (null != other) { + map.putAll(other.map) + } + } + + override fun toString(): String { + return "MXUsersDevicesMap $map" + } +} + +inline fun <T> MXUsersDevicesMap<T>.forEach(action: (String, String, T) -> Unit) { + userIds.forEach { userId -> + getUserDeviceIds(userId)?.forEach { deviceId -> + getObject(userId, deviceId)?.let { + action(userId, deviceId, it) + } + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/OlmDecryptionResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/OlmDecryptionResult.kt similarity index 93% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/OlmDecryptionResult.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/OlmDecryptionResult.kt index 955f57afba..9cf2bf75fb 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/OlmDecryptionResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/OlmDecryptionResult.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.algorithms.olm +package org.matrix.android.sdk.api.session.crypto.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedBodyFileInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/OutgoingGossipingRequestState.kt similarity index 63% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedBodyFileInfo.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/OutgoingGossipingRequestState.kt index 90f97b65eb..8c1bdf6768 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedBodyFileInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/OutgoingGossipingRequestState.kt @@ -13,17 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest -import org.matrix.olm.OlmPkMessage +package org.matrix.android.sdk.api.session.crypto.model -/** - * Build from a OlmPkMessage object - * - * @param olmPkMessage OlmPkMessage - */ -class EncryptedBodyFileInfo(olmPkMessage: OlmPkMessage) { - var ciphertext = olmPkMessage.mCipherText - var mac = olmPkMessage.mMac - var ephemeral = olmPkMessage.mEphemeralKey +enum class OutgoingGossipingRequestState { + UNSENT, + SENDING, + SENT, + CANCELLING, + CANCELLED, + FAILED_TO_SEND, + FAILED_TO_CANCEL } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingRoomKeyRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/OutgoingRoomKeyRequest.kt similarity index 72% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingRoomKeyRequest.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/OutgoingRoomKeyRequest.kt index 88025952db..5f35cc908f 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingRoomKeyRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/OutgoingRoomKeyRequest.kt @@ -14,10 +14,10 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto +package org.matrix.android.sdk.api.session.crypto.model import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody +import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequest /** * Represents an outgoing room key request @@ -25,14 +25,14 @@ import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody @JsonClass(generateAdapter = true) data class OutgoingRoomKeyRequest( // RequestBody - var requestBody: RoomKeyRequestBody?, + val requestBody: RoomKeyRequestBody?, // list of recipients for the request - override var recipients: Map<String, List<String>>, + override val recipients: Map<String, List<String>>, // Unique id for this request. Used for both // an id within the request for later pairing with a cancellation, and for // the transaction id when sending the to_device messages to our local - override var requestId: String, // current state of this request - override var state: OutgoingGossipingRequestState + override val requestId: String, // current state of this request + override val state: OutgoingGossipingRequestState // transaction id for the cancellation, if any // override var cancellationTxnId: String? = null ) : OutgoingGossipingRequest { @@ -43,9 +43,7 @@ data class OutgoingRoomKeyRequest( * @return the room id. */ val roomId: String? - get() = if (null != requestBody) { - requestBody!!.roomId - } else null + get() = requestBody?.roomId /** * Used only for log. @@ -53,7 +51,5 @@ data class OutgoingRoomKeyRequest( * @return the session id */ val sessionId: String? - get() = if (null != requestBody) { - requestBody!!.sessionId - } else null + get() = requestBody?.sessionId } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/RoomEncryptionTrustLevel.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomEncryptionTrustLevel.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/RoomEncryptionTrustLevel.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomEncryptionTrustLevel.kt index 8ba99ad70b..68c7496d58 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/RoomEncryptionTrustLevel.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomEncryptionTrustLevel.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.api.crypto +package org.matrix.android.sdk.api.session.crypto.model /** * RoomEncryptionTrustLevel represents the trust level in an encrypted room. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/RoomKeyRequestBody.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomKeyRequestBody.kt similarity index 96% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/RoomKeyRequestBody.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomKeyRequestBody.kt index 3eae2585a5..15163248dc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/RoomKeyRequestBody.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomKeyRequestBody.kt @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest + +package org.matrix.android.sdk.api.session.crypto.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/RoomKeyShareRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomKeyShareRequest.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/RoomKeyShareRequest.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomKeyShareRequest.kt index 68fbf0b805..b6bb4c55af 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/RoomKeyShareRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/RoomKeyShareRequest.kt @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest + +package org.matrix.android.sdk.api.session.crypto.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/SecretShareRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/SecretShareRequest.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/SecretShareRequest.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/SecretShareRequest.kt index a4eeb50d8b..6009077806 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/SecretShareRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/SecretShareRequest.kt @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest + +package org.matrix.android.sdk.api.session.crypto.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/SendToDeviceObject.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/SendToDeviceObject.kt similarity index 91% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/SendToDeviceObject.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/SendToDeviceObject.kt index b3a76b2a7c..b866cb76cc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/SendToDeviceObject.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/SendToDeviceObject.kt @@ -14,6 +14,6 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest +package org.matrix.android.sdk.api.session.crypto.model interface SendToDeviceObject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/UnsignedDeviceInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/UnsignedDeviceInfo.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/UnsignedDeviceInfo.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/UnsignedDeviceInfo.kt index 5f316486b6..1d9d1fce3e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/UnsignedDeviceInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/model/UnsignedDeviceInfo.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest +package org.matrix.android.sdk.api.session.crypto.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/VerificationState.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationState.kt similarity index 87% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/VerificationState.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationState.kt index 54276a6b51..fe855278a5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/crypto/VerificationState.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/crypto/verification/VerificationState.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.api.crypto +package org.matrix.android.sdk.api.session.crypto.verification enum class VerificationState { REQUEST, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt index f1304f6216..1ce51a2bde 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/Event.kt @@ -22,6 +22,8 @@ import org.json.JSONObject import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.model.message.MessageContent @@ -34,8 +36,7 @@ import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.threads.ThreadDetails import org.matrix.android.sdk.api.util.ContentUtils import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent +import org.matrix.android.sdk.api.util.MatrixJsonParser import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.session.presence.model.PresenceContent import timber.log.Timber @@ -46,7 +47,7 @@ typealias Content = JsonDict * This methods is a facility method to map a json content to a model. */ inline fun <reified T> Content?.toModel(catchError: Boolean = true): T? { - val moshi = MoshiProvider.providesMoshi() + val moshi = MatrixJsonParser.getMoshi() val moshiAdapter = moshi.adapter(T::class.java) return try { moshiAdapter.fromJsonValue(this) @@ -65,7 +66,7 @@ inline fun <reified T> Content?.toModel(catchError: Boolean = true): T? { */ @Suppress("UNCHECKED_CAST") inline fun <reified T> T.toContent(): Content { - val moshi = MoshiProvider.providesMoshi() + val moshi = MatrixJsonParser.getMoshi() val moshiAdapter = moshi.adapter(T::class.java) return moshiAdapter.toJsonValue(this) as Content } @@ -202,7 +203,9 @@ data class Event( fun getDecryptedTextSummary(): String? { if (isRedacted()) return "Message Deleted" val text = getDecryptedValue() ?: run { - if (isPoll()) { return getPollQuestion() ?: "created a poll." } + if (isPoll()) { + return getPollQuestion() ?: "created a poll." + } return null } @@ -300,57 +303,67 @@ data class Event( } } +/** + * Return the value of "content.msgtype", if the Event type is "m.room.message" + * and if the content has it, and if it is a String + */ +fun Event.getMsgType(): String? { + if (getClearType() != EventType.MESSAGE) return null + return getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY) as? String +} + fun Event.isTextMessage(): Boolean { - return getClearType() == EventType.MESSAGE && - when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { - MessageType.MSGTYPE_TEXT, - MessageType.MSGTYPE_EMOTE, - MessageType.MSGTYPE_NOTICE -> true - else -> false - } + return when (getMsgType()) { + MessageType.MSGTYPE_TEXT, + MessageType.MSGTYPE_EMOTE, + MessageType.MSGTYPE_NOTICE -> true + else -> false + } } fun Event.isImageMessage(): Boolean { - return getClearType() == EventType.MESSAGE && - when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { - MessageType.MSGTYPE_IMAGE -> true - else -> false - } + return when (getMsgType()) { + MessageType.MSGTYPE_IMAGE -> true + else -> false + } } fun Event.isVideoMessage(): Boolean { - return getClearType() == EventType.MESSAGE && - when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { - MessageType.MSGTYPE_VIDEO -> true - else -> false - } + return when (getMsgType()) { + MessageType.MSGTYPE_VIDEO -> true + else -> false + } } fun Event.isAudioMessage(): Boolean { - return getClearType() == EventType.MESSAGE && - when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { - MessageType.MSGTYPE_AUDIO -> true - else -> false - } + return when (getMsgType()) { + MessageType.MSGTYPE_AUDIO -> true + else -> false + } } fun Event.isFileMessage(): Boolean { - return getClearType() == EventType.MESSAGE && - when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { - MessageType.MSGTYPE_FILE -> true - else -> false - } + return when (getMsgType()) { + MessageType.MSGTYPE_FILE -> true + else -> false + } } fun Event.isAttachmentMessage(): Boolean { - return getClearType() == EventType.MESSAGE && - when (getClearContent()?.get(MessageContent.MSG_TYPE_JSON_KEY)) { - MessageType.MSGTYPE_IMAGE, - MessageType.MSGTYPE_AUDIO, - MessageType.MSGTYPE_VIDEO, - MessageType.MSGTYPE_FILE -> true - else -> false - } + return when (getMsgType()) { + MessageType.MSGTYPE_IMAGE, + MessageType.MSGTYPE_AUDIO, + MessageType.MSGTYPE_VIDEO, + MessageType.MSGTYPE_FILE -> true + else -> false + } +} + +fun Event.isLocationMessage(): Boolean { + return when (getMsgType()) { + MessageType.MSGTYPE_LOCATION -> true + else -> false + } } fun Event.isPoll(): Boolean = getClearType() in EventType.POLL_START || getClearType() in EventType.POLL_END @@ -400,7 +413,7 @@ fun Event.isEdition(): Boolean { return getRelationContentForType(RelationType.REPLACE)?.eventId != null } -fun Event.getPresenceContent(): PresenceContent? { +internal fun Event.getPresenceContent(): PresenceContent? { return content.toModel<PresenceContent>() } @@ -411,4 +424,5 @@ fun Event.getPollContent(): MessagePollContent? { return content.toModel<MessagePollContent>() } -fun Event.supportsNotification() = this.getClearType() in EventType.MESSAGE + EventType.POLL_START +fun Event.supportsNotification() = + this.getClearType() in EventType.MESSAGE + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt index 855801e79e..fa3a9f6acd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/EventType.kt @@ -49,7 +49,8 @@ object EventType { const val STATE_ROOM_JOIN_RULES = "m.room.join_rules" const val STATE_ROOM_GUEST_ACCESS = "m.room.guest_access" const val STATE_ROOM_POWER_LEVELS = "m.room.power_levels" - private const val STATE_ROOM_BEACON_INFO_PREFIX = "org.matrix.msc3489.beacon_info." + val STATE_ROOM_BEACON_INFO = listOf("org.matrix.msc3672.beacon_info", "m.beacon_info") + val BEACON_LOCATION_DATA = listOf("org.matrix.msc3672.beacon", "m.beacon") const val STATE_SPACE_CHILD = "m.space.child" @@ -121,12 +122,4 @@ object EventType { type == CALL_REJECT || type == CALL_REPLACES } - - /** - * Returns an event type like org.matrix.msc3489.beacon_info.@userid:matrix.org.1648814272273 - */ - fun generateBeaconInfoStateEventType(userId: String): String { - val uniqueId = System.currentTimeMillis() - return "$STATE_ROOM_BEACON_INFO_PREFIX$userId.$uniqueId" - } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/EncryptedEventContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/EncryptedEventContent.kt similarity index 93% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/EncryptedEventContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/EncryptedEventContent.kt index 93a6377bbb..4f39bb61e1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/EncryptedEventContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/EncryptedEventContent.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.event +package org.matrix.android.sdk.api.session.events.model.content import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/EncryptionEventContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/EncryptionEventContent.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/EncryptionEventContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/EncryptionEventContent.kt index dd76ae1d8e..103293ba83 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/EncryptionEventContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/EncryptionEventContent.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.event +package org.matrix.android.sdk.api.session.events.model.content import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/OlmEventContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/OlmEventContent.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/OlmEventContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/OlmEventContent.kt index 6fd0627022..b972dd20bb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/OlmEventContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/OlmEventContent.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.event +package org.matrix.android.sdk.api.session.events.model.content import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/OlmPayloadContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/OlmPayloadContent.kt similarity index 96% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/OlmPayloadContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/OlmPayloadContent.kt index 3ce9d36f90..6060ab5c4b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/OlmPayloadContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/OlmPayloadContent.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.event +package org.matrix.android.sdk.api.session.events.model.content import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/RoomKeyContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/RoomKeyContent.kt similarity index 90% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/RoomKeyContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/RoomKeyContent.kt index 7fa0e83725..43a47b818f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/RoomKeyContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/RoomKeyContent.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.event +package org.matrix.android.sdk.api.session.events.model.content import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/RoomKeyWithHeldContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/RoomKeyWithHeldContent.kt similarity index 98% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/RoomKeyWithHeldContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/RoomKeyWithHeldContent.kt index 4c462357db..a577daf9e4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/RoomKeyWithHeldContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/RoomKeyWithHeldContent.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.event +package org.matrix.android.sdk.api.session.events.model.content import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/SecretSendEventContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/SecretSendEventContent.kt similarity index 93% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/SecretSendEventContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/SecretSendEventContent.kt index 4dcca04e94..5099aba403 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/SecretSendEventContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/events/model/content/SecretSendEventContent.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.event +package org.matrix.android.sdk.api.session.events.model.content import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/file/FileService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/file/FileService.kt index f76e4be440..72f8019ada 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/file/FileService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/file/FileService.kt @@ -17,11 +17,11 @@ package org.matrix.android.sdk.api.session.file import android.net.Uri +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt +import org.matrix.android.sdk.api.session.crypto.attachments.toElementToDecrypt import org.matrix.android.sdk.api.session.room.model.message.MessageWithAttachmentContent import org.matrix.android.sdk.api.session.room.model.message.getFileName import org.matrix.android.sdk.api.session.room.model.message.getFileUrl -import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt -import org.matrix.android.sdk.internal.crypto.attachments.toElementToDecrypt import java.io.File /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt index 9db3876b74..597c1a0ca8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/homeserver/HomeServerCapabilities.kt @@ -54,7 +54,7 @@ data class HomeServerCapabilities( /** * True if the home server support threading */ - var canUseThreading: Boolean = false + val canUseThreading: Boolean = false ) { enum class RoomCapabilitySupport { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt index a22cd572fa..fdcb30a5c8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/IdentityService.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.api.session.identity -import org.matrix.android.sdk.internal.session.identity.model.SignInvitationResult +import org.matrix.android.sdk.api.session.identity.model.SignInvitationResult /** * Provides access to the identity server configuration and services identity server can provide diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/model/SignInvitationResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/model/SignInvitationResult.kt similarity index 64% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/model/SignInvitationResult.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/model/SignInvitationResult.kt index 27a3f3209f..b1662b9cf8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/model/SignInvitationResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/identity/model/SignInvitationResult.kt @@ -1,5 +1,5 @@ /* - * Copyright 2021 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,18 +14,26 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.identity.model +package org.matrix.android.sdk.api.session.identity.model import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) data class SignInvitationResult( - /** The Matrix user ID of the user accepting the invitation.*/ + /** + * The Matrix user ID of the user accepting the invitation. + */ val mxid: String, - /** The Matrix user ID of the user who sent the invitation.*/ + /** + * The Matrix user ID of the user who sent the invitation. + */ val sender: String, - /**The token from the call to store- invite..*/ + /** + * The token from the call to store- invite.. + */ val signatures: Map<String, *>, - /** The token for the invitation */ + /** + * The token for the invitation + */ val token: String ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/SyncStatusService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/SyncStatusService.kt index daab6d9761..267436916e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/SyncStatusService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/initsync/SyncStatusService.kt @@ -28,7 +28,7 @@ interface SyncStatusService { abstract class InitialSyncStatus : Status() object Idle : InitialSyncStatus() - data class Progressing( + data class InitialSyncProgressing( val initSyncStep: InitSyncStep, val percentProgress: Int = 0 ) : InitialSyncStatus() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt index c1c1a385b5..700e292b0c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/RoomService.kt @@ -19,6 +19,8 @@ package org.matrix.android.sdk.api.session.room import androidx.lifecycle.LiveData import androidx.paging.PagedList import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.identity.model.SignInvitationResult +import org.matrix.android.sdk.api.session.room.alias.RoomAliasDescription import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary @@ -27,8 +29,6 @@ import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.session.room.peeking.PeekResult import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount import org.matrix.android.sdk.api.util.Optional -import org.matrix.android.sdk.internal.session.identity.model.SignInvitationResult -import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription /** * This interface defines methods to get rooms. It's implemented at the session level. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/RoomAliasDescription.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/alias/RoomAliasDescription.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/RoomAliasDescription.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/alias/RoomAliasDescription.kt index d1f93c50be..ce7b03d35b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/RoomAliasDescription.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/alias/RoomAliasDescription.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.room.alias +package org.matrix.android.sdk.api.session.room.alias import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt index 445d16b72b..6967e0c455 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/crypto/RoomCryptoService.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.api.session.room.crypto -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM interface RoomCryptoService { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/EventAnnotationsSummary.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/EventAnnotationsSummary.kt index 3a4912e457..0238eb6c8d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/EventAnnotationsSummary.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/EventAnnotationsSummary.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.api.session.room.model data class EventAnnotationsSummary( - var eventId: String, - var reactionsSummary: List<ReactionAggregatedSummary> = emptyList(), - var editSummary: EditAggregatedSummary? = null, - var pollResponseSummary: PollResponseAggregatedSummary? = null, - var referencesAggregatedSummary: ReferencesAggregatedSummary? = null + val eventId: String, + val reactionsSummary: List<ReactionAggregatedSummary> = emptyList(), + val editSummary: EditAggregatedSummary? = null, + val pollResponseSummary: PollResponseAggregatedSummary? = null, + val referencesAggregatedSummary: ReferencesAggregatedSummary? = null ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PollResponseAggregatedSummary.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PollResponseAggregatedSummary.kt index a15d8be084..b16852e47d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PollResponseAggregatedSummary.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PollResponseAggregatedSummary.kt @@ -16,13 +16,11 @@ package org.matrix.android.sdk.api.session.room.model data class PollResponseAggregatedSummary( - - var aggregatedContent: PollSummaryContent? = null, - + val aggregatedContent: PollSummaryContent? = null, // If set the poll is closed (Clients SHOULD NOT consider responses after the close event) - var closedTime: Long? = null, + val closedTime: Long? = null, // Clients SHOULD validate that the option in the relationship is a valid option, and ignore the response if invalid - var nbOptions: Int = 0, + val nbOptions: Int = 0, // The list of the eventIDs used to build the summary (might be out of sync if chunked received from message chunk) val sourceEvents: List<String>, val localEchos: List<String> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PollSummaryContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PollSummaryContent.kt index f1e4354314..09458ff12e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PollSummaryContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/PollSummaryContent.kt @@ -24,13 +24,13 @@ import com.squareup.moshi.JsonClass */ @JsonClass(generateAdapter = true) data class PollSummaryContent( - var myVote: String? = null, - // Array of VoteInfo, list is constructed so that there is only one vote by user + val myVote: String? = null, + // List of VoteInfo, list is constructed so that there is only one vote by user // And that optionIndex is valid - var votes: List<VoteInfo>? = null, - var votesSummary: Map<String, VoteSummary>? = null, - var totalVotes: Int = 0, - var winnerVoteCount: Int = 0 + val votes: List<VoteInfo>? = null, + val votesSummary: Map<String, VoteSummary>? = null, + val totalVotes: Int = 0, + val winnerVoteCount: Int = 0 ) @JsonClass(generateAdapter = true) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/ReferencesAggregatedContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/ReferencesAggregatedContent.kt index 664d042e18..c6b94c5dd1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/ReferencesAggregatedContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/ReferencesAggregatedContent.kt @@ -17,7 +17,7 @@ package org.matrix.android.sdk.api.session.room.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.api.crypto.VerificationState +import org.matrix.android.sdk.api.session.crypto.verification.VerificationState /** * Contains an aggregated summary info of the references. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomEncryptionAlgorithm.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomEncryptionAlgorithm.kt index f681216929..5f728a4ed4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomEncryptionAlgorithm.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomEncryptionAlgorithm.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.api.session.room.model -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM sealed class RoomEncryptionAlgorithm { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt index 150b2c62d0..e9b2f8cdcd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/RoomSummary.kt @@ -17,7 +17,7 @@ package org.matrix.android.sdk.api.session.room.model import de.spiritcroc.matrixsdk.StaticScSdkHelper -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.presence.model.UserPresence import org.matrix.android.sdk.api.session.room.model.tag.RoomTag import org.matrix.android.sdk.api.session.room.send.UserDraft diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomParams.kt index 5667906000..ce1e0e0d14 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomParams.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/create/CreateRoomParams.kt @@ -17,12 +17,12 @@ package org.matrix.android.sdk.api.session.room.model.create import android.net.Uri +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.room.model.GuestAccess import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent import org.matrix.android.sdk.api.session.room.model.RoomDirectoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM open class CreateRoomParams { /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/livelocation/LiveLocationBeaconContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/livelocation/LiveLocationBeaconContent.kt index e08d5b629b..106e76eafd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/livelocation/LiveLocationBeaconContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/livelocation/LiveLocationBeaconContent.kt @@ -18,15 +18,30 @@ package org.matrix.android.sdk.api.session.room.model.livelocation import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.room.model.message.LocationAsset import org.matrix.android.sdk.api.session.room.model.message.LocationAssetType +import org.matrix.android.sdk.api.session.room.model.message.MessageContent +import org.matrix.android.sdk.api.session.room.model.message.MessageLiveLocationContent +import org.matrix.android.sdk.api.session.room.model.message.MessageType +import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent @JsonClass(generateAdapter = true) data class LiveLocationBeaconContent( + /** + * Local message type, not from server + */ + @Transient + override val msgType: String = MessageType.MSGTYPE_LIVE_LOCATION_STATE, + + @Json(name = "body") override val body: String = "", + @Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null, + @Json(name = "m.new_content") override val newContent: Content? = null, + /** * Indicates user's intent to share ephemeral location. */ - @Json(name = "org.matrix.msc3489.beacon_info") val unstableBeaconInfo: BeaconInfo? = null, + @Json(name = "org.matrix.msc3672.beacon_info") val unstableBeaconInfo: BeaconInfo? = null, @Json(name = "m.beacon_info") val beaconInfo: BeaconInfo? = null, /** * Beacon creation timestamp. @@ -37,8 +52,18 @@ data class LiveLocationBeaconContent( * Live location asset type. */ @Json(name = "org.matrix.msc3488.asset") val unstableLocationAsset: LocationAsset = LocationAsset(LocationAssetType.SELF), - @Json(name = "m.asset") val locationAsset: LocationAsset? = null -) { + @Json(name = "m.asset") val locationAsset: LocationAsset? = null, + + /** + * Client side tracking of the last location + */ + var lastLocationContent: MessageLiveLocationContent? = null, + + /** + * Client side tracking of whether the beacon has timed out. + */ + var hasTimedOut: Boolean = false +) : MessageContent { fun getBestBeaconInfo() = beaconInfo ?: unstableBeaconInfo diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/FileInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/FileInfo.kt index f21074096e..fa18bfd21f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/FileInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/FileInfo.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.api.session.room.model.message import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo @JsonClass(generateAdapter = true) data class FileInfo( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/ImageInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/ImageInfo.kt index c38ef5bc27..0099208320 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/ImageInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/ImageInfo.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.api.session.room.model.message import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo @JsonClass(generateAdapter = true) data class ImageInfo( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageAudioContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageAudioContent.kt index ebf3d127ce..76a612b51b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageAudioContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageAudioContent.kt @@ -18,10 +18,10 @@ package org.matrix.android.sdk.api.session.room.model.message import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo @JsonClass(generateAdapter = true) data class MessageAudioContent( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageFileContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageFileContent.kt index 78f9a5d2f2..b5303e6c5d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageFileContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageFileContent.kt @@ -19,9 +19,9 @@ package org.matrix.android.sdk.api.session.room.model.message import android.webkit.MimeTypeMap import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo @JsonClass(generateAdapter = true) data class MessageFileContent( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageImageContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageImageContent.kt index ea7ab50688..f0caf52041 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageImageContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageImageContent.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.api.session.room.model.message import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo @JsonClass(generateAdapter = true) data class MessageImageContent( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageLiveLocationContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageLiveLocationContent.kt new file mode 100644 index 0000000000..548dc85369 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageLiveLocationContent.kt @@ -0,0 +1,52 @@ +/* + * Copyright 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.session.room.model.message + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.events.model.Content +import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent + +@JsonClass(generateAdapter = true) +data class MessageLiveLocationContent( + /** + * Local message type, not from server + */ + @Transient + override val msgType: String = MessageType.MSGTYPE_LIVE_LOCATION, + + @Json(name = "body") override val body: String = "", + @Json(name = "m.relates_to") override val relatesTo: RelationDefaultContent? = null, + @Json(name = "m.new_content") override val newContent: Content? = null, + + /** + * See [MSC3488](https://github.com/matrix-org/matrix-doc/blob/matthew/location/proposals/3488-location.md) + */ + @Json(name = "org.matrix.msc3488.location") val unstableLocationInfo: LocationInfo? = null, + @Json(name = "m.location") val locationInfo: LocationInfo? = null, + + /** + * Exact time that the data in the event refers to (milliseconds since the UNIX epoch) + */ + @Json(name = "org.matrix.msc3488.ts") val unstableTimestampAsMilliseconds: Long? = null, + @Json(name = "m.ts") val timestampAsMilliseconds: Long? = null +) : MessageContent { + + fun getBestLocationInfo() = locationInfo ?: unstableLocationInfo + + fun getBestTimestampAsMilliseconds() = timestampAsMilliseconds ?: unstableTimestampAsMilliseconds +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt index 8e1d4d3d75..3d774cadb2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageStickerContent.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.api.session.room.model.message import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo @JsonClass(generateAdapter = true) data class MessageStickerContent( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt index 2a6138ae60..106bf2e030 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageType.kt @@ -33,10 +33,14 @@ object MessageType { const val MSGTYPE_STICKER_LOCAL = "org.matrix.android.sdk.sticker" // Fake message types for poll events to be able to inherit them from MessageContent - // Because poll events are not message events and they don't hanve msgtype field + // Because poll events are not message events and they don't have msgtype field const val MSGTYPE_POLL_START = "org.matrix.android.sdk.poll.start" const val MSGTYPE_POLL_RESPONSE = "org.matrix.android.sdk.poll.response" const val MSGTYPE_CONFETTI = "nic.custom.confetti" const val MSGTYPE_SNOWFALL = "io.element.effect.snowfall" + + // Fake message types for live location events to be able to inherit them from MessageContent + const val MSGTYPE_LIVE_LOCATION_STATE = "org.matrix.android.sdk.livelocation.state" + const val MSGTYPE_LIVE_LOCATION = "org.matrix.android.sdk.livelocation" } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVideoContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVideoContent.kt index e1b0cd8607..9266a0fb0f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVideoContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageVideoContent.kt @@ -18,9 +18,9 @@ package org.matrix.android.sdk.api.session.room.model.message import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo @JsonClass(generateAdapter = true) data class MessageVideoContent( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageWithAttachmentContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageWithAttachmentContent.kt index 7870db4f65..95dfb6b864 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageWithAttachmentContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/MessageWithAttachmentContent.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.api.session.room.model.message -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo /** * Interface for message which can contains an encrypted file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/VideoInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/VideoInfo.kt index 8a36c26313..28f3a47d11 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/VideoInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/model/message/VideoInfo.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.api.session.room.model.message import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo @JsonClass(generateAdapter = true) data class VideoInfo( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt index 9f8b1d93d7..af7ab11df1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/send/SendService.kt @@ -146,6 +146,15 @@ interface SendService { */ fun sendLocation(latitude: Double, longitude: Double, uncertainty: Double?, isUserLocation: Boolean): Cancelable + /** + * Send a live location event to the room. beacon_info state event has to be sent before sending live location updates. + * @param beaconInfoEventId event id of the initial beacon info state event + * @param latitude required latitude of the location + * @param longitude required longitude of the location + * @param uncertainty Accuracy of the location in meters + */ + fun sendLiveLocation(beaconInfoEventId: String, latitude: Double, longitude: Double, uncertainty: Double?): Cancelable + /** * Remove this failed message from the timeline * @param localEcho the unsent local echo diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt index e9b0e4f676..f645f3ebf9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/state/StateService.kt @@ -66,6 +66,19 @@ interface StateService { */ suspend fun deleteAvatar() + /** + * Stops sharing live location in the room + * @param userId user id + */ + suspend fun stopLiveLocation(userId: String) + + /** + * Returns beacon info state event of a user + * @param userId user id who is sharing location + * @param filterOnlyLive filters only ongoing live location sharing beacons if true else ended event is included + */ + suspend fun getLiveLocationBeaconInfo(userId: String, filterOnlyLive: Boolean): Event? + /** * Send a state event to the room * @param eventType The type of event to send. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomSummaryConstants.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomSummaryConstants.kt index 88d05c1930..b4b2ea8b8f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomSummaryConstants.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/summary/RoomSummaryConstants.kt @@ -33,7 +33,7 @@ object RoomSummaryConstants { EventType.ENCRYPTED, EventType.STICKER, EventType.REACTION, - ) + EventType.POLL_START + ) + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO // SC addition | this is the Element behaviour previous to Element v1.0.7 val PREVIEWABLE_TYPES_ALL = listOf( @@ -53,7 +53,7 @@ object RoomSummaryConstants { EventType.STICKER, EventType.REACTION, EventType.STATE_ROOM_CREATE - ) + EventType.POLL_START + ) + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO // SC addition | no reactions in here val PREVIEWABLE_ORIGINAL_CONTENT_TYPES = listOf( @@ -64,5 +64,5 @@ object RoomSummaryConstants { EventType.CALL_ANSWER, EventType.ENCRYPTED, EventType.STICKER - ) + EventType.POLL_START + ) + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/taggedevents/TaggedEventsContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/taggedevents/TaggedEventsContent.kt similarity index 97% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/taggedevents/TaggedEventsContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/taggedevents/TaggedEventsContent.kt index 1b19d27e1d..521a2315e4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/taggedevents/TaggedEventsContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/taggedevents/TaggedEventsContent.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.room.taggedevents +package org.matrix.android.sdk.api.session.room.taggedevents import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt index 1b01efc074..a2ae8bfeb5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/room/timeline/TimelineEvent.kt @@ -29,6 +29,7 @@ import org.matrix.android.sdk.api.session.events.model.isSticker import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.EventAnnotationsSummary import org.matrix.android.sdk.api.session.room.model.ReadReceipt +import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationBeaconContent import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent import org.matrix.android.sdk.api.session.room.model.message.MessageStickerContent @@ -55,7 +56,7 @@ data class TimelineEvent( * It's not unique on the timeline as it's reset on each chunk. */ val displayIndex: Int, - var ownedByThreadChunk: Boolean = false, + val ownedByThreadChunk: Boolean = false, val senderInfo: SenderInfo, val annotations: EventAnnotationsSummary? = null, val readReceipts: List<ReadReceipt> = emptyList() @@ -136,9 +137,10 @@ fun TimelineEvent.getEditedEventId(): String? { */ fun TimelineEvent.getLastMessageContent(): MessageContent? { return when (root.getClearType()) { - EventType.STICKER -> root.getClearContent().toModel<MessageStickerContent>() - in EventType.POLL_START -> (annotations?.editSummary?.latestContent ?: root.getClearContent()).toModel<MessagePollContent>() - else -> (annotations?.editSummary?.latestContent ?: root.getClearContent()).toModel() + EventType.STICKER -> root.getClearContent().toModel<MessageStickerContent>() + in EventType.POLL_START -> (annotations?.editSummary?.latestContent ?: root.getClearContent()).toModel<MessagePollContent>() + in EventType.STATE_ROOM_BEACON_INFO -> (annotations?.editSummary?.latestContent ?: root.getClearContent()).toModel<LiveLocationBeaconContent>() + else -> (annotations?.editSummary?.latestContent ?: root.getClearContent()).toModel() } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SsssKeyCreationInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SsssKeyCreationInfo.kt index eeb1b31f9c..7a91a16c8c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SsssKeyCreationInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SsssKeyCreationInfo.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.api.session.securestorage data class SsssKeyCreationInfo( val keyId: String = "", - var content: SecretStorageKeyContent?, + val content: SecretStorageKeyContent?, val recoveryKey: String = "", val keySpec: SsssKeySpec ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SsssKeySpec.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SsssKeySpec.kt index f791ea4e86..03efb9b3db 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SsssKeySpec.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/securestorage/SsssKeySpec.kt @@ -17,8 +17,8 @@ package org.matrix.android.sdk.api.session.securestorage import org.matrix.android.sdk.api.listeners.ProgressListener +import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey import org.matrix.android.sdk.internal.crypto.keysbackup.deriveKey -import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey /** Tag class */ interface SsssKeySpec diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt index 41c4e7eed1..f4460b7659 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/SpaceService.kt @@ -22,7 +22,7 @@ import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.RoomSortOrder import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams import org.matrix.android.sdk.api.session.room.model.RoomSummary -import org.matrix.android.sdk.internal.session.space.peeking.SpacePeekResult +import org.matrix.android.sdk.api.session.space.peeking.SpacePeekResult typealias SpaceSummaryQueryParams = RoomSummaryQueryParams diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/SpacePeekResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/peeking/SpacePeekResult.kt similarity index 88% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/SpacePeekResult.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/peeking/SpacePeekResult.kt index a2ffd8221a..06dbd12d7a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/SpacePeekResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/space/peeking/SpacePeekResult.kt @@ -14,11 +14,18 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.space.peeking +package org.matrix.android.sdk.api.session.space.peeking import org.matrix.android.sdk.api.session.room.peeking.PeekResult -// TODO Move to api package +sealed class SpacePeekResult { + abstract class SpacePeekError : SpacePeekResult() + data class FailedToResolve(val spaceId: String, val roomPeekResult: PeekResult) : SpacePeekError() + data class NotSpaceType(val spaceId: String) : SpacePeekError() + + data class Success(val summary: SpacePeekSummary) : SpacePeekResult() +} + data class SpacePeekSummary( val idOrAlias: String, val roomPeekResult: PeekResult.Success, @@ -28,30 +35,18 @@ data class SpacePeekSummary( interface ISpaceChild { val id: String val roomPeekResult: PeekResult - -// val default: Boolean? val order: String? } data class SpaceChildPeekResult( override val id: String, override val roomPeekResult: PeekResult, -// override val default: Boolean? = null, override val order: String? = null ) : ISpaceChild data class SpaceSubChildPeekResult( override val id: String, override val roomPeekResult: PeekResult, -// override val default: Boolean?, override val order: String?, val children: List<ISpaceChild> ) : ISpaceChild - -sealed class SpacePeekResult { - abstract class SpacePeekError : SpacePeekResult() - data class FailedToResolve(val spaceId: String, val roomPeekResult: PeekResult) : SpacePeekError() - data class NotSpaceType(val spaceId: String) : SpacePeekError() - - data class Success(val summary: SpacePeekSummary) : SpacePeekResult() -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStrategy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/InitialSyncStrategy.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStrategy.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/InitialSyncStrategy.kt index 4bc866b36d..461d816ea7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/InitialSyncStrategy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/InitialSyncStrategy.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync +package org.matrix.android.sdk.api.session.sync var initialSyncStrategy: InitialSyncStrategy = InitialSyncStrategy.Optimized() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/job/SyncService.kt similarity index 98% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncService.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/job/SyncService.kt index 97ae9b3a68..ac81be2174 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/sync/job/SyncService.kt @@ -1,11 +1,11 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -13,7 +13,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.session.sync.job + +package org.matrix.android.sdk.api.session.sync.job import android.app.Service import android.content.Intent diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/GetTermsResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/GetTermsResponse.kt index e6d33cade6..b7bdc2b770 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/GetTermsResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/GetTermsResponse.kt @@ -16,8 +16,6 @@ package org.matrix.android.sdk.api.session.terms -import org.matrix.android.sdk.internal.session.terms.TermsResponse - data class GetTermsResponse( val serverResponse: TermsResponse, val alreadyAcceptedTermUrls: Set<String> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/TermsResponse.kt similarity index 93% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsResponse.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/TermsResponse.kt index a185e0b80f..9a30b4d764 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/TermsResponse.kt @@ -14,12 +14,12 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.session.terms +package org.matrix.android.sdk.api.session.terms import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.auth.data.LocalizedFlowDataLoginTerms import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.auth.registration.LocalizedFlowDataLoginTerms /** * This class represent a localized privacy policy for registration Flow. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/TermsService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/TermsService.kt index e64cf1872e..6c357b2224 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/TermsService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/terms/TermsService.kt @@ -16,8 +16,6 @@ package org.matrix.android.sdk.api.session.terms -import org.matrix.android.sdk.internal.session.terms.TermsResponse - interface TermsService { enum class ServiceType { IntegrationManager, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadDetails.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadDetails.kt index d6937d5b26..c8fe1c85ea 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadDetails.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/threads/ThreadDetails.kt @@ -29,7 +29,7 @@ data class ThreadDetails( val threadSummarySenderInfo: SenderInfo? = null, val threadSummaryLatestEvent: Event? = null, val lastMessageTimestamp: Long? = null, - var threadNotificationState: ThreadNotificationState = ThreadNotificationState.NO_NEW_MESSAGE, + val threadNotificationState: ThreadNotificationState = ThreadNotificationState.NO_NEW_MESSAGE, val isThread: Boolean = false, val lastRootThreadEdition: String? = null ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DefaultBaseAuth.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/uia/DefaultBaseAuth.kt similarity index 91% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DefaultBaseAuth.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/uia/DefaultBaseAuth.kt index bbb4a3a654..865e02daf2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DefaultBaseAuth.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/uia/DefaultBaseAuth.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest +package org.matrix.android.sdk.api.session.uia import org.matrix.android.sdk.api.auth.UIABaseAuth diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/InteractiveAuthenticationFlow.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/uia/InteractiveAuthenticationFlow.kt similarity index 94% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/InteractiveAuthenticationFlow.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/uia/InteractiveAuthenticationFlow.kt index d66bcfb274..a78c047221 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/data/InteractiveAuthenticationFlow.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/uia/InteractiveAuthenticationFlow.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.auth.data +package org.matrix.android.sdk.api.session.uia import com.squareup.moshi.Json import com.squareup.moshi.JsonClass diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt index cd4fb216d3..063abdb5a0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/UserService.kt @@ -75,11 +75,14 @@ interface UserService { /** * Ignore users + * Note: once done, for the change to take effect, you have to request an initial sync. + * This may be improved in the future */ suspend fun ignoreUserIds(userIds: List<String>) /** * Un-ignore some users + * Note: once done, for the change to take effect, you have to request an initial sync. */ suspend fun unIgnoreUserIds(userIds: List<String>) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt index 54ae9e54f6..79c86f3f23 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/session/user/model/User.kt @@ -16,6 +16,9 @@ package org.matrix.android.sdk.api.session.user.model +import org.matrix.android.sdk.api.session.profile.ProfileService +import org.matrix.android.sdk.api.util.JsonDict + /** * Data class which holds information about a user. * It can be retrieved with [org.matrix.android.sdk.api.session.user.UserService] @@ -27,4 +30,14 @@ data class User( */ val displayName: String? = null, val avatarUrl: String? = null -) +) { + + companion object { + + fun fromJson(userId: String, json: JsonDict) = User( + userId = userId, + displayName = json[ProfileService.DISPLAY_NAME_KEY] as? String, + avatarUrl = json[ProfileService.AVATAR_URL_KEY] as? String + ) + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/settings/LightweightSettingsStorage.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/settings/LightweightSettingsStorage.kt new file mode 100644 index 0000000000..8dd20a702b --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/settings/LightweightSettingsStorage.kt @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.settings + +interface LightweightSettingsStorage { + fun setThreadMessagesEnabled(enabled: Boolean) + fun areThreadMessagesEnabled(): Boolean +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/Base64.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/Base64.kt new file mode 100644 index 0000000000..e0596c1325 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/Base64.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.util + +import android.util.Base64 + +fun ByteArray.toBase64NoPadding(): String { + return Base64.encodeToString(this, Base64.NO_PADDING or Base64.NO_WRAP) +} + +fun String.fromBase64(): ByteArray { + return Base64.decode(this, Base64.DEFAULT) +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Hash.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/Hash.kt similarity index 95% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Hash.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/Hash.kt index 47f20913ec..7465eed3ae 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Hash.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/Hash.kt @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.util +package org.matrix.android.sdk.api.util import java.security.MessageDigest import java.util.Locale diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt index 650b8cc26d..4f5f4f82d9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixItem.kt @@ -37,6 +37,7 @@ sealed class MatrixItem( override val displayName: String? = null, override val avatarUrl: String? = null) : MatrixItem(id, displayName?.removeSuffix(IRC_PATTERN), avatarUrl) { + init { if (BuildConfig.DEBUG) checkId() } @@ -200,7 +201,7 @@ fun RoomMemberSummary.toMatrixItem() = MatrixItem.UserItem(userId, displayName, fun SenderInfo.toMatrixItem() = MatrixItem.UserItem(userId, disambiguatedDisplayName, avatarUrl) -fun SenderInfo.toMatrixItemOrNull() = tryOrNull { MatrixItem.UserItem(userId, disambiguatedDisplayName, avatarUrl) } +fun SenderInfo.toMatrixItemOrNull() = tryOrNull { MatrixItem.UserItem(userId, disambiguatedDisplayName, avatarUrl) } fun SpaceChildInfo.toMatrixItem() = if (roomType == RoomType.SPACE) { MatrixItem.SpaceItem(childRoomId, name ?: canonicalAlias, avatarUrl) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixJsonParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixJsonParser.kt new file mode 100644 index 0000000000..48a41667b2 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/MatrixJsonParser.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.util + +import com.squareup.moshi.Moshi +import org.matrix.android.sdk.internal.di.MoshiProvider + +/** + * Entry point to get a Json parser + */ +object MatrixJsonParser { + /** + * @return a Moshi Json parser instance, configured to handle some Matrix Event contents + */ + fun getMoshi(): Moshi { + return MoshiProvider.providesMoshi() + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/SuspendMatrixCallback.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/SuspendMatrixCallback.kt similarity index 96% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/SuspendMatrixCallback.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/SuspendMatrixCallback.kt index 145fc92fea..381dfb65fa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/SuspendMatrixCallback.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/SuspendMatrixCallback.kt @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.util +package org.matrix.android.sdk.api.util import org.matrix.android.sdk.api.MatrixCallback import kotlin.coroutines.resume diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/TextContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/TextContent.kt new file mode 100644 index 0000000000..fe12d7b1cf --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/util/TextContent.kt @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.api.util + +/** + * Contains a text and eventually a formatted text + */ +data class TextContent( + val text: String, + val formattedText: String? = null +) { + fun takeFormatted() = formattedText ?: text +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultHomeServerHistoryService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultHomeServerHistoryService.kt index 7415938ebc..c57ce6875d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultHomeServerHistoryService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultHomeServerHistoryService.kt @@ -23,7 +23,7 @@ import org.matrix.android.sdk.internal.database.model.KnownServerUrlEntity import org.matrix.android.sdk.internal.di.GlobalDatabase import javax.inject.Inject -class DefaultHomeServerHistoryService @Inject constructor( +internal class DefaultHomeServerHistoryService @Inject constructor( @GlobalDatabase private val monarchy: Monarchy ) : HomeServerHistoryService { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo001.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo001.kt index 627f4e16bc..a8d5e29689 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo001.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo001.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.auth.db.PendingSessionEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber -class MigrateAuthTo001(realm: DynamicRealm) : RealmMigrator(realm, 1) { +internal class MigrateAuthTo001(realm: DynamicRealm) : RealmMigrator(realm, 1) { override fun doMigrate(realm: DynamicRealm) { Timber.d("Create PendingSessionEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo002.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo002.kt index 6b133f8580..ef3a3e7f9b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo002.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo002.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.auth.db.SessionParamsEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber -class MigrateAuthTo002(realm: DynamicRealm) : RealmMigrator(realm, 2) { +internal class MigrateAuthTo002(realm: DynamicRealm) : RealmMigrator(realm, 2) { override fun doMigrate(realm: DynamicRealm) { Timber.d("Add boolean isTokenValid in SessionParamsEntity, with value true") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo003.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo003.kt index 9319ec9987..2584df1895 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo003.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo003.kt @@ -24,7 +24,7 @@ import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber -class MigrateAuthTo003(realm: DynamicRealm) : RealmMigrator(realm, 3) { +internal class MigrateAuthTo003(realm: DynamicRealm) : RealmMigrator(realm, 3) { override fun doMigrate(realm: DynamicRealm) { Timber.d("Update SessionParamsEntity primary key, to allow several sessions with the same userId") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo004.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo004.kt index 4a9b9022d5..6dfec6a1aa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo004.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/migration/MigrateAuthTo004.kt @@ -24,7 +24,7 @@ import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber -class MigrateAuthTo004(realm: DynamicRealm) : RealmMigrator(realm, 4) { +internal class MigrateAuthTo004(realm: DynamicRealm) : RealmMigrator(realm, 4) { override fun doMigrate(realm: DynamicRealm) { Timber.d("Update SessionParamsEntity to add HomeServerConnectionConfig.homeServerUriBase value") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/AuthParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/AuthParams.kt index 23fdbc613a..cb17207741 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/AuthParams.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/AuthParams.kt @@ -88,15 +88,3 @@ internal data class AuthParams( } } } - -@JsonClass(generateAdapter = true) -data class ThreePidCredentials( - @Json(name = "client_secret") - val clientSecret: String? = null, - - @Json(name = "id_server") - val idServer: String? = null, - - @Json(name = "sid") - val sid: String? = null -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/SuccessResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/SuccessResult.kt index 9b158cce90..c666eec749 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/SuccessResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/SuccessResult.kt @@ -21,7 +21,7 @@ import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.extensions.orFalse @JsonClass(generateAdapter = true) -data class SuccessResult( +internal data class SuccessResult( @Json(name = "success") val success: Boolean? ) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/NewDeviceContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/ThreePidCredentials.kt similarity index 64% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/NewDeviceContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/ThreePidCredentials.kt index 2a63b4bee8..296ccadf91 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/event/NewDeviceContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/ThreePidCredentials.kt @@ -1,5 +1,5 @@ /* - * Copyright 2020 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,18 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.event + +package org.matrix.android.sdk.internal.auth.registration import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -data class NewDeviceContent( - // the device id - @Json(name = "device_id") - val deviceId: String? = null, +internal data class ThreePidCredentials( + @Json(name = "client_secret") + val clientSecret: String? = null, - // the room ids list - @Json(name = "rooms") - val rooms: List<String>? = null + @Json(name = "id_server") + val idServer: String? = null, + + @Json(name = "sid") + val sid: String? = null ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/ValidationCodeBody.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/ValidationCodeBody.kt index b6f3e83929..ae71ae3a08 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/ValidationCodeBody.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/registration/ValidationCodeBody.kt @@ -23,7 +23,7 @@ import com.squareup.moshi.JsonClass * This object is used to send a code received by SMS to validate Msisdn ownership */ @JsonClass(generateAdapter = true) -data class ValidationCodeBody( +internal data class ValidationCodeBody( @Json(name = "client_secret") val clientSecret: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CancelGossipRequestWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CancelGossipRequestWorker.kt index 3a5f8e7668..98950374ed 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CancelGossipRequestWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/CancelGossipRequestWorker.kt @@ -21,11 +21,12 @@ import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.failure.shouldBeRetried +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.api.session.crypto.model.OutgoingGossipingRequestState import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.internal.SessionManager -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.rest.ShareRequestCancellation import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt index db44abc36f..6a57d94677 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DefaultCryptoService.kt @@ -32,6 +32,8 @@ import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_OLM import org.matrix.android.sdk.api.crypto.MXCryptoConfig import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.failure.Failure @@ -39,14 +41,31 @@ import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.NewSessionListener +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListener +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DevicesListResponse +import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult +import org.matrix.android.sdk.api.session.crypto.model.IncomingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.MXDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.MXEncryptEventContentResult +import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.api.session.crypto.model.OutgoingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent +import org.matrix.android.sdk.api.session.events.model.content.RoomKeyContent +import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent +import org.matrix.android.sdk.api.session.events.model.content.SecretSendEventContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility @@ -61,21 +80,8 @@ import org.matrix.android.sdk.internal.crypto.algorithms.IMXWithHeldExtension import org.matrix.android.sdk.internal.crypto.algorithms.megolm.MXMegolmEncryptionFactory import org.matrix.android.sdk.internal.crypto.algorithms.olm.MXOlmEncryptionFactory import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult -import org.matrix.android.sdk.internal.crypto.model.MXDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXEncryptEventContentResult import org.matrix.android.sdk.internal.crypto.model.MXKey.Companion.KEY_SIGNED_CURVE_25519_TYPE -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent -import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent -import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent -import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.model.toRest import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt index 494e6d7cc7..6cae2d0935 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/DeviceListManager.kt @@ -21,10 +21,10 @@ import kotlinx.coroutines.launch import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.auth.data.Credentials -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.CryptoInfoMapper -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask import org.matrix.android.sdk.internal.session.SessionScope diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt index 00efd3d6a8..1c8bce7377 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/EventDecryptor.kt @@ -21,15 +21,17 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.MatrixCoroutineDispatchers +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_OLM import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.OlmEventContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevicesAction import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.event.OlmEventContent import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.extensions.foldToCallback diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DummyContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/GossipRequestType.kt similarity index 75% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DummyContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/GossipRequestType.kt index 53d6e4a80a..266c1a2744 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DummyContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/GossipRequestType.kt @@ -13,10 +13,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.matrix.android.sdk.internal.crypto.model.rest -/** - * Class representing the dummy content - * Ref: https://matrix.org/docs/spec/client_server/latest#id82 - */ -typealias DummyContent = Unit +package org.matrix.android.sdk.internal.crypto + +internal enum class GossipRequestType { + KEY, + SECRET +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt index 34bef61c98..a78444dff9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/InboundGroupSessionStore.kt @@ -30,7 +30,7 @@ import java.util.Timer import java.util.TimerTask import javax.inject.Inject -data class InboundGroupSessionHolder( +internal data class InboundGroupSessionHolder( val wrapper: OlmInboundGroupSessionWrapper2, val mutex: Mutex = Mutex() ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt index 220f25ec80..3a409cf3fd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingGossipingRequestManager.kt @@ -20,21 +20,26 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.auth.data.Credentials +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.api.crypto.MXCryptoConfig import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME +import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListener +import org.matrix.android.sdk.api.session.crypto.model.GossipingRequestState +import org.matrix.android.sdk.api.session.crypto.model.GossipingToDeviceObject +import org.matrix.android.sdk.api.session.crypto.model.IncomingRequestCancellation +import org.matrix.android.sdk.api.session.crypto.model.IncomingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.IncomingSecretShareRequest +import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.util.toBase64NoPadding import org.matrix.android.sdk.internal.crypto.algorithms.IMXGroupEncryption -import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding -import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey import org.matrix.android.sdk.internal.crypto.model.rest.GossipingDefaultContent -import org.matrix.android.sdk.internal.crypto.model.rest.GossipingToDeviceObject -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.createUniqueTxnId import org.matrix.android.sdk.internal.di.SessionId diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingShareRequestCommon.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingShareRequestCommon.kt index 86e9610148..97c369db3e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingShareRequestCommon.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/IncomingShareRequestCommon.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.internal.crypto -interface IncomingShareRequestCommon { +internal interface IncomingShareRequestCommon { /** * The user id */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXCryptoAlgorithms.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXCryptoAlgorithms.kt index 07881c7d79..5a5ee9e696 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXCryptoAlgorithms.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXCryptoAlgorithms.kt @@ -16,6 +16,9 @@ package org.matrix.android.sdk.internal.crypto +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_OLM + // TODO Update comment internal object MXCryptoAlgorithms { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt index e5ffa0ed7d..f8235bf344 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXMegolmExportEncryption.kt @@ -33,7 +33,7 @@ import kotlin.math.min /** * Utility class to import/export the crypto data */ -object MXMegolmExportEncryption { +internal object MXMegolmExportEncryption { private const val HEADER_LINE = "-----BEGIN MEGOLM SESSION DATA-----" private const val TRAILER_LINE = "-----END MEGOLM SESSION DATA-----" diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt index 501fb42db2..4947761f05 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MXOlmDevice.kt @@ -22,11 +22,11 @@ import kotlinx.coroutines.sync.withLock import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.util.JSON_DICT_PARAMETERIZED_TYPE import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.crypto.algorithms.megolm.MXOutboundSessionInfo import org.matrix.android.sdk.internal.crypto.algorithms.megolm.SharedWithHelper -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper2 import org.matrix.android.sdk.internal.crypto.model.OlmSessionWrapper import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt index caff2d76f1..f6bc9a9148 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MegolmSessionData.kt @@ -23,7 +23,7 @@ import com.squareup.moshi.JsonClass * The type of object we use for importing and exporting megolm session data. */ @JsonClass(generateAdapter = true) -data class MegolmSessionData( +internal data class MegolmSessionData( /** * The algorithm used. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MyDeviceInfoHolder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MyDeviceInfoHolder.kt index 70846515a7..9798d21576 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MyDeviceInfoHolder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/MyDeviceInfoHolder.kt @@ -17,8 +17,8 @@ package org.matrix.android.sdk.internal.crypto import org.matrix.android.sdk.api.auth.data.Credentials -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.session.SessionScope import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OneTimeKeysUploader.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OneTimeKeysUploader.kt index 4aebe091c4..792c9a25dc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OneTimeKeysUploader.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OneTimeKeysUploader.kt @@ -31,7 +31,7 @@ import kotlin.math.min // The spec recommend a 5mn delay, but due to federation // or server downtime we give it a bit more time (1 hour) -const val FALLBACK_KEY_FORGET_DELAY = 60 * 60_000L +private const val FALLBACK_KEY_FORGET_DELAY = 60 * 60_000L @SessionScope internal class OneTimeKeysUploader @Inject constructor( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingGossipingRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingGossipingRequest.kt index 8e13daec94..2438e01102 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingGossipingRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingGossipingRequest.kt @@ -16,10 +16,12 @@ package org.matrix.android.sdk.internal.crypto -interface OutgoingGossipingRequest { - var recipients: Map<String, List<String>> - var requestId: String - var state: OutgoingGossipingRequestState +import org.matrix.android.sdk.api.session.crypto.model.OutgoingGossipingRequestState + +internal interface OutgoingGossipingRequest { + val recipients: Map<String, List<String>> + val requestId: String + val state: OutgoingGossipingRequestState // transaction id for the cancellation, if any // var cancellationTxnId: String? } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingGossipingRequestManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingGossipingRequestManager.kt index fd60e43260..e6f6ac5053 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingGossipingRequestManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingGossipingRequestManager.kt @@ -20,7 +20,9 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch import org.matrix.android.sdk.api.MatrixCoroutineDispatchers -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody +import org.matrix.android.sdk.api.session.crypto.model.OutgoingGossipingRequestState +import org.matrix.android.sdk.api.session.crypto.model.OutgoingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.createUniqueTxnId import org.matrix.android.sdk.internal.crypto.util.RequestIdHelper diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingSecretRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingSecretRequest.kt index def7a1567a..2ba2f5c817 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingSecretRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/OutgoingSecretRequest.kt @@ -17,12 +17,13 @@ package org.matrix.android.sdk.internal.crypto import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.OutgoingGossipingRequestState /** * Represents an outgoing room key request */ @JsonClass(generateAdapter = true) -class OutgoingSecretRequest( +internal class OutgoingSecretRequest( // Secret Name val secretName: String?, // list of recipients for the request diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RoomDecryptorProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RoomDecryptorProvider.kt index 89fb43ef2e..dab806a565 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RoomDecryptorProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/RoomDecryptorProvider.kt @@ -16,6 +16,8 @@ package org.matrix.android.sdk.internal.crypto +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.session.crypto.NewSessionListener import org.matrix.android.sdk.internal.crypto.algorithms.IMXDecrypting import org.matrix.android.sdk.internal.crypto.algorithms.megolm.MXMegolmDecryptionFactory import org.matrix.android.sdk.internal.crypto.algorithms.olm.MXOlmDecryptionFactory @@ -74,7 +76,7 @@ internal class RoomDecryptorProvider @Inject constructor( this.newSessionListener = object : NewSessionListener { override fun onNewSession(roomId: String?, senderKey: String, sessionId: String) { // PR reviewer: the parameter has been renamed so is now in conflict with the parameter of getOrCreateRoomDecryptor - newSessionListeners.forEach { + newSessionListeners.toList().forEach { try { it.onNewSession(roomId, senderKey, sessionId) } catch (e: Throwable) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipRequestWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipRequestWorker.kt index 3129ccae3b..dbdea97411 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipRequestWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipRequestWorker.kt @@ -21,14 +21,16 @@ import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.failure.shouldBeRetried +import org.matrix.android.sdk.api.session.crypto.model.GossipingToDeviceObject +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.api.session.crypto.model.OutgoingGossipingRequestState +import org.matrix.android.sdk.api.session.crypto.model.OutgoingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.RoomKeyShareRequest +import org.matrix.android.sdk.api.session.crypto.model.SecretShareRequest import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.internal.SessionManager -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.rest.GossipingToDeviceObject -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyShareRequest -import org.matrix.android.sdk.internal.crypto.model.rest.SecretShareRequest import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.createUniqueTxnId diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt index ff206a3c96..fd472fe73b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/SendGossipWorker.kt @@ -21,14 +21,15 @@ import androidx.work.WorkerParameters import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.failure.shouldBeRetried +import org.matrix.android.sdk.api.session.crypto.model.GossipingRequestState +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.SecretSendEventContent import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevicesAction import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.crypto.tasks.createUniqueTxnId @@ -38,8 +39,11 @@ import org.matrix.android.sdk.internal.worker.SessionWorkerParams import timber.log.Timber import javax.inject.Inject -internal class SendGossipWorker(context: Context, params: WorkerParameters, sessionManager: SessionManager) : - SessionSafeCoroutineWorker<SendGossipWorker.Params>(context, params, sessionManager, Params::class.java) { +internal class SendGossipWorker( + context: Context, + params: WorkerParameters, + sessionManager: SessionManager +) : SessionSafeCoroutineWorker<SendGossipWorker.Params>(context, params, sessionManager, Params::class.java) { @JsonClass(generateAdapter = true) internal data class Params( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt index 87c176612d..fffc2b4d4b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForDevicesAction.kt @@ -21,11 +21,11 @@ import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.logger.LoggerTag +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.MXOlmDevice -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.MXKey import org.matrix.android.sdk.internal.crypto.model.MXOlmSessionResult -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.tasks.ClaimOneTimeKeysForUsersDeviceTask import org.matrix.android.sdk.internal.session.SessionScope import timber.log.Timber diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForUsersAction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForUsersAction.kt index a3cfbd91f0..fc211537a6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForUsersAction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/EnsureOlmSessionsForUsersAction.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.crypto.actions +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.MXOlmDevice import org.matrix.android.sdk.internal.crypto.model.MXOlmSessionResult -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import timber.log.Timber import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt index 953681c40f..2d5e87d9ab 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MegolmSessionDataImporter.kt @@ -21,13 +21,13 @@ import com.zhuinden.monarchy.Monarchy import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import org.matrix.android.sdk.api.listeners.ProgressListener +import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult +import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.MXOlmDevice import org.matrix.android.sdk.internal.crypto.MegolmSessionData import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager import org.matrix.android.sdk.internal.crypto.RoomDecryptorProvider import org.matrix.android.sdk.internal.crypto.algorithms.megolm.MXMegolmDecryption -import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MessageEncrypter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MessageEncrypter.kt index 4e158602c8..9bbbab4992 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MessageEncrypter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/MessageEncrypter.kt @@ -16,11 +16,11 @@ package org.matrix.android.sdk.internal.crypto.actions +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_OLM import org.matrix.android.sdk.api.logger.LoggerTag +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.events.model.Content -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_OLM import org.matrix.android.sdk.internal.crypto.MXOlmDevice -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedMessage import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.UserId diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/SetDeviceVerificationAction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/SetDeviceVerificationAction.kt index 40eddc82bd..60181138fb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/SetDeviceVerificationAction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/actions/SetDeviceVerificationAction.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.internal.crypto.actions -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.di.UserId diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt index 51ddd74442..2ea4e1dd29 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXDecrypting.kt @@ -17,10 +17,10 @@ package org.matrix.android.sdk.internal.crypto.algorithms import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.IncomingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.IncomingSecretShareRequest +import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest -import org.matrix.android.sdk.internal.crypto.IncomingSecretShareRequest -import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXWithHeldExtension.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXWithHeldExtension.kt index 91f10adf4c..585bcdbbde 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXWithHeldExtension.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/IMXWithHeldExtension.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.internal.crypto.algorithms -import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent +import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent internal interface IMXWithHeldExtension { fun onRoomKeyWithHeldEvent(withHeldInfo: RoomKeyWithHeldContent) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt index 72df59023a..4c407c9eb9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmDecryption.kt @@ -23,26 +23,26 @@ import kotlinx.coroutines.sync.withLock import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.NewSessionListener +import org.matrix.android.sdk.api.session.crypto.model.ForwardedRoomKeyContent +import org.matrix.android.sdk.api.session.crypto.model.IncomingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent +import org.matrix.android.sdk.api.session.events.model.content.RoomKeyContent +import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.internal.crypto.DeviceListManager -import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest -import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult import org.matrix.android.sdk.internal.crypto.MXOlmDevice -import org.matrix.android.sdk.internal.crypto.NewSessionListener import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevicesAction import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter import org.matrix.android.sdk.internal.crypto.algorithms.IMXDecrypting import org.matrix.android.sdk.internal.crypto.algorithms.IMXWithHeldExtension import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent -import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyContent -import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent -import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import org.matrix.android.sdk.internal.session.StreamEventsManager diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt index cf9733dc2d..f052194230 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXMegolmEncryption.kt @@ -21,24 +21,24 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCoroutineDispatchers +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.api.session.crypto.model.forEach import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent +import org.matrix.android.sdk.api.session.events.model.content.WithHeldCode import org.matrix.android.sdk.internal.crypto.DeviceListManager -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.crypto.MXOlmDevice import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevicesAction import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter import org.matrix.android.sdk.internal.crypto.algorithms.IMXEncrypting import org.matrix.android.sdk.internal.crypto.algorithms.IMXGroupEncryption import org.matrix.android.sdk.internal.crypto.keysbackup.DefaultKeysBackupService -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent -import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode -import org.matrix.android.sdk.internal.crypto.model.forEach import org.matrix.android.sdk.internal.crypto.model.toDebugCount import org.matrix.android.sdk.internal.crypto.model.toDebugString import org.matrix.android.sdk.internal.crypto.repository.WarnOnUnknownDeviceRepository diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXOutboundSessionInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXOutboundSessionInfo.kt index b70e6c1f80..091abd4974 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXOutboundSessionInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/MXOutboundSessionInfo.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.crypto.algorithms.megolm -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import timber.log.Timber internal class MXOutboundSessionInfo( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/SharedWithHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/SharedWithHelper.kt index a64e5af0d3..59d78c3e05 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/SharedWithHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/megolm/SharedWithHelper.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.crypto.algorithms.megolm -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore internal class SharedWithHelper( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt index afa249801d..0db8700852 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmDecryption.kt @@ -19,26 +19,27 @@ package org.matrix.android.sdk.internal.crypto.algorithms.olm import kotlinx.coroutines.sync.withLock import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.content.OlmEventContent +import org.matrix.android.sdk.api.session.events.model.content.OlmPayloadContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.util.JSON_DICT_PARAMETERIZED_TYPE import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult import org.matrix.android.sdk.internal.crypto.MXOlmDevice import org.matrix.android.sdk.internal.crypto.algorithms.IMXDecrypting -import org.matrix.android.sdk.internal.crypto.model.event.OlmEventContent -import org.matrix.android.sdk.internal.crypto.model.event.OlmPayloadContent import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.util.convertFromUTF8 import timber.log.Timber private val loggerTag = LoggerTag("MXOlmDecryption", LoggerTag.CRYPTO) + internal class MXOlmDecryption( // The olm device interface private val olmDevice: MXOlmDevice, // the matrix userId private val userId: String) : - IMXDecrypting { + IMXDecrypting { @Throws(MXCryptoError::class) override suspend fun decryptEvent(event: Event, timeline: String): MXEventDecryptionResult { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt index 63f2533ac3..7fdfd5a287 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/algorithms/olm/MXOlmEncryption.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.crypto.algorithms.olm +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.internal.crypto.DeviceListManager @@ -23,7 +24,6 @@ import org.matrix.android.sdk.internal.crypto.MXOlmDevice import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForUsersAction import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter import org.matrix.android.sdk.internal.crypto.algorithms.IMXEncrypting -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore internal class MXOlmEncryption( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt index cef86e8b5e..f21f5e05e1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/api/CryptoApi.kt @@ -15,9 +15,9 @@ */ package org.matrix.android.sdk.internal.crypto.api +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DevicesListResponse import org.matrix.android.sdk.internal.crypto.model.rest.DeleteDeviceParams -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeyChangesResponse import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimBody import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimResponse diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/EncryptionResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/EncryptionResult.kt index ba5baba60d..80090cf4a8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/EncryptionResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/EncryptionResult.kt @@ -16,12 +16,12 @@ package org.matrix.android.sdk.internal.crypto.attachments -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo /** * Define the result of an encryption file */ internal data class EncryptionResult( - var encryptedFileInfo: EncryptedFileInfo, - var encryptedByteArray: ByteArray + val encryptedFileInfo: EncryptedFileInfo, + val encryptedByteArray: ByteArray ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt index 70730326da..91b6af6fc3 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MXEncryptedAttachments.kt @@ -17,8 +17,9 @@ package org.matrix.android.sdk.internal.crypto.attachments import android.util.Base64 -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileKey +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileKey import org.matrix.android.sdk.internal.util.base64ToBase64Url import org.matrix.android.sdk.internal.util.base64ToUnpaddedBase64 import org.matrix.android.sdk.internal.util.base64UrlToBase64 diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MatrixDigestCheckInputStream.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MatrixDigestCheckInputStream.kt deleted file mode 100644 index 2cbe0e3702..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/attachments/MatrixDigestCheckInputStream.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.attachments - -import android.util.Base64 -import org.matrix.android.sdk.internal.util.base64ToUnpaddedBase64 -import java.io.FilterInputStream -import java.io.IOException -import java.io.InputStream -import java.security.MessageDigest - -class MatrixDigestCheckInputStream( - inputStream: InputStream?, - private val expectedDigest: String -) : FilterInputStream(inputStream) { - - private val digest = MessageDigest.getInstance("SHA-256") - - @Throws(IOException::class) - override fun read(): Int { - val b = `in`.read() - if (b >= 0) { - digest.update(b.toByte()) - } - - if (b == -1) { - ensureDigest() - } - return b - } - - @Throws(IOException::class) - override fun read( - b: ByteArray, - off: Int, - len: Int): Int { - val n = `in`.read(b, off, len) - if (n > 0) { - digest.update(b, off, n) - } - - if (n == -1) { - ensureDigest() - } - return n - } - - @Throws(IOException::class) - private fun ensureDigest() { - val currentDigestValue = base64ToUnpaddedBase64(Base64.encodeToString(digest.digest(), Base64.DEFAULT)) - if (currentDigestValue != expectedDigest) { - throw IOException("Bad digest") - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/ComputeTrustTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/ComputeTrustTask.kt index b470ab34bb..02ea943284 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/ComputeTrustTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/ComputeTrustTask.kt @@ -17,9 +17,9 @@ package org.matrix.android.sdk.internal.crypto.crosssigning import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCoroutineDispatchers -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.task.Task diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt index 83de06a668..ba1718688f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/DefaultCrossSigningService.kt @@ -26,13 +26,20 @@ import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustResult import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.PrivateKeysInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.UserTrustResult +import org.matrix.android.sdk.api.session.crypto.crosssigning.isCrossSignedVerified +import org.matrix.android.sdk.api.session.crypto.crosssigning.isLocallyVerified +import org.matrix.android.sdk.api.session.crypto.crosssigning.isVerified +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.api.util.fromBase64 import org.matrix.android.sdk.internal.crypto.DeviceListManager -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.UploadSignatureQueryBuilder import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo import org.matrix.android.sdk.internal.crypto.tasks.InitializeCrossSigningTask import org.matrix.android.sdk.internal.crypto.tasks.UploadSignaturesTask import org.matrix.android.sdk.internal.di.SessionId diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/Extensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/Extensions.kt index cf2d6aa269..16098e5210 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/Extensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/Extensions.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.crypto.crosssigning import android.util.Base64 -import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.util.JsonCanonicalizer import timber.log.Timber @@ -29,14 +29,6 @@ internal fun CryptoCrossSigningKey.canonicalSignable(): String { return JsonCanonicalizer.getCanonicalJson(Map::class.java, signalableJSONDictionary()) } -fun ByteArray.toBase64NoPadding(): String { - return Base64.encodeToString(this, Base64.NO_PADDING or Base64.NO_WRAP) -} - -fun String.fromBase64(): ByteArray { - return Base64.decode(this, Base64.DEFAULT) -} - /** * Decode the base 64. Return null in case of bad format. Should be used when parsing received data from external source */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt index 794ab04533..74f0f5745d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/crosssigning/UpdateTrustWorker.kt @@ -22,9 +22,12 @@ import com.squareup.moshi.JsonClass import io.realm.Realm import io.realm.RealmConfiguration import io.realm.kotlin.where -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.UserTrustResult +import org.matrix.android.sdk.api.session.crypto.crosssigning.isCrossSignedVerified +import org.matrix.android.sdk.api.session.crypto.crosssigning.isVerified +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.store.db.mapper.CrossSigningKeysMapper diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt index 954c2dbe43..e63a6dc791 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/DefaultKeysBackupService.kt @@ -28,30 +28,37 @@ import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.auth.data.Credentials +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.failure.MatrixError import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.listeners.StepProgressListener +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupVersionTrust +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupVersionTrustSignature +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersion +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersionResult +import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupAuthData +import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreationInfo +import org.matrix.android.sdk.api.session.crypto.keysbackup.SavedKeyBackupKeyInfo +import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey +import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey +import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult +import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult +import org.matrix.android.sdk.api.util.awaitCallback +import org.matrix.android.sdk.api.util.fromBase64 import org.matrix.android.sdk.internal.crypto.MXOlmDevice import org.matrix.android.sdk.internal.crypto.MegolmSessionData import org.matrix.android.sdk.internal.crypto.ObjectSigner import org.matrix.android.sdk.internal.crypto.actions.MegolmSessionDataImporter -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust -import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrustSignature -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo import org.matrix.android.sdk.internal.crypto.keysbackup.model.SignalableMegolmBackupAuthData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeyBackupData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysBackupData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.RoomKeysBackupData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.CreateKeysBackupVersionTask @@ -68,12 +75,8 @@ import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionD import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreRoomSessionsDataTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.StoreSessionsDataTask import org.matrix.android.sdk.internal.crypto.keysbackup.tasks.UpdateKeysBackupVersionTask -import org.matrix.android.sdk.internal.crypto.keysbackup.util.computeRecoveryKey -import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey -import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper2 import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntity import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.di.UserId @@ -84,7 +87,6 @@ import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.task.TaskThread import org.matrix.android.sdk.internal.task.configureWith import org.matrix.android.sdk.internal.util.JsonCanonicalizer -import org.matrix.android.sdk.internal.util.awaitCallback import org.matrix.olm.OlmException import org.matrix.olm.OlmPkDecryption import org.matrix.olm.OlmPkEncryption @@ -407,20 +409,22 @@ internal class DefaultKeysBackupService @Inject constructor( */ @WorkerThread private fun getKeysBackupTrustBg(keysBackupVersion: KeysVersionResult): KeysBackupVersionTrust { - val keysBackupVersionTrust = KeysBackupVersionTrust() val authData = keysBackupVersion.getAuthDataAsMegolmBackupAuthData() if (authData == null || authData.publicKey.isEmpty() || authData.signatures.isNullOrEmpty()) { Timber.v("getKeysBackupTrust: Key backup is absent or missing required data") - return keysBackupVersionTrust + return KeysBackupVersionTrust(usable = false) } val mySigs = authData.signatures[userId] if (mySigs.isNullOrEmpty()) { Timber.v("getKeysBackupTrust: Ignoring key backup because it lacks any signatures from this user") - return keysBackupVersionTrust + return KeysBackupVersionTrust(usable = false) } + var keysBackupVersionTrustIsUsable = false + val keysBackupVersionTrustSignatures = mutableListOf<KeysBackupVersionTrustSignature>() + for ((keyId, mySignature) in mySigs) { // XXX: is this how we're supposed to get the device id? var deviceId: String? = null @@ -447,19 +451,23 @@ internal class DefaultKeysBackupService @Inject constructor( } if (isSignatureValid && device.isVerified) { - keysBackupVersionTrust.usable = true + keysBackupVersionTrustIsUsable = true } } - val signature = KeysBackupVersionTrustSignature() - signature.device = device - signature.valid = isSignatureValid - signature.deviceId = deviceId - keysBackupVersionTrust.signatures.add(signature) + val signature = KeysBackupVersionTrustSignature( + deviceId = deviceId, + device = device, + valid = isSignatureValid, + ) + keysBackupVersionTrustSignatures.add(signature) } } - return keysBackupVersionTrust + return KeysBackupVersionTrust( + usable = keysBackupVersionTrustIsUsable, + signatures = keysBackupVersionTrustSignatures + ) } override fun trustKeysBackupVersion(keysBackupVersion: KeysVersionResult, @@ -586,21 +594,28 @@ internal class DefaultKeysBackupService @Inject constructor( cryptoCoroutineScope.launch(coroutineDispatchers.main) { try { - val keysBackupVersion = getKeysBackupLastVersionTask.execute(Unit) - val recoveryKey = computeRecoveryKey(secret.fromBase64()) - if (isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysBackupVersion)) { - awaitCallback<Unit> { - trustKeysBackupVersion(keysBackupVersion, true, it) + when (val keysBackupLastVersionResult = getKeysBackupLastVersionTask.execute(Unit)) { + KeysBackupLastVersionResult.NoKeysBackup -> { + Timber.d("No keys backup found") } - val importResult = awaitCallback<ImportRoomKeysResult> { - restoreKeysWithRecoveryKey(keysBackupVersion, recoveryKey, null, null, null, it) + is KeysBackupLastVersionResult.KeysBackup -> { + val keysBackupVersion = keysBackupLastVersionResult.keysVersionResult + val recoveryKey = computeRecoveryKey(secret.fromBase64()) + if (isValidRecoveryKeyForKeysBackupVersion(recoveryKey, keysBackupVersion)) { + awaitCallback<Unit> { + trustKeysBackupVersion(keysBackupVersion, true, it) + } + val importResult = awaitCallback<ImportRoomKeysResult> { + restoreKeysWithRecoveryKey(keysBackupVersion, recoveryKey, null, null, null, it) + } + withContext(coroutineDispatchers.crypto) { + cryptoStore.saveBackupRecoveryKey(recoveryKey, keysBackupVersion.version) + } + Timber.i("onSecretKeyGossip: Recovered keys $importResult") + } else { + Timber.e("onSecretKeyGossip: Recovery key is not valid ${keysBackupVersion.version}") + } } - withContext(coroutineDispatchers.crypto) { - cryptoStore.saveBackupRecoveryKey(recoveryKey, keysBackupVersion.version) - } - Timber.i("onSecretKeyGossip: Recovered keys ${importResult.successfullyNumberOfImportedKeys} out of ${importResult.totalNumberOfKeys}") - } else { - Timber.e("onSecretKeyGossip: Recovery key is not valid ${keysBackupVersion.version}") } } catch (failure: Throwable) { Timber.e("onSecretKeyGossip: failed to trust key backup version ${keysBackupVersion?.version}") @@ -875,63 +890,49 @@ internal class DefaultKeysBackupService @Inject constructor( .executeBy(taskExecutor) } - override fun getCurrentVersion(callback: MatrixCallback<KeysVersionResult?>) { + override fun getCurrentVersion(callback: MatrixCallback<KeysBackupLastVersionResult>) { getKeysBackupLastVersionTask .configureWith { - this.callback = object : MatrixCallback<KeysVersionResult> { - override fun onSuccess(data: KeysVersionResult) { - callback.onSuccess(data) - } - - override fun onFailure(failure: Throwable) { - if (failure is Failure.ServerError && - failure.error.code == MatrixError.M_NOT_FOUND) { - // Workaround because the homeserver currently returns M_NOT_FOUND when there is no key backup - callback.onSuccess(null) - } else { - // Transmit the error - callback.onFailure(failure) - } - } - } + this.callback = callback } .executeBy(taskExecutor) } override fun forceUsingLastVersion(callback: MatrixCallback<Boolean>) { - getCurrentVersion(object : MatrixCallback<KeysVersionResult?> { - override fun onSuccess(data: KeysVersionResult?) { + getCurrentVersion(object : MatrixCallback<KeysBackupLastVersionResult> { + override fun onSuccess(data: KeysBackupLastVersionResult) { val localBackupVersion = keysBackupVersion?.version - val serverBackupVersion = data?.version - - if (serverBackupVersion == null) { - if (localBackupVersion == null) { - // No backup on the server, and backup is not active - callback.onSuccess(true) - } else { - // No backup on the server, and we are currently backing up, so stop backing up - callback.onSuccess(false) - resetKeysBackupData() - keysBackupVersion = null - keysBackupStateManager.state = KeysBackupState.Disabled - } - } else { - if (localBackupVersion == null) { - // backup on the server, and backup is not active - callback.onSuccess(false) - // Do a check - checkAndStartWithKeysBackupVersion(data) - } else { - // Backup on the server, and we are currently backing up, compare version - if (localBackupVersion == serverBackupVersion) { - // We are already using the last version of the backup + when (data) { + KeysBackupLastVersionResult.NoKeysBackup -> { + if (localBackupVersion == null) { + // No backup on the server, and backup is not active callback.onSuccess(true) } else { - // We are not using the last version, so delete the current version we are using on the server + // No backup on the server, and we are currently backing up, so stop backing up callback.onSuccess(false) + resetKeysBackupData() + keysBackupVersion = null + keysBackupStateManager.state = KeysBackupState.Disabled + } + } + is KeysBackupLastVersionResult.KeysBackup -> { + if (localBackupVersion == null) { + // backup on the server, and backup is not active + callback.onSuccess(false) + // Do a check + checkAndStartWithKeysBackupVersion(data.keysVersionResult) + } else { + // Backup on the server, and we are currently backing up, compare version + if (localBackupVersion == data.keysVersionResult.version) { + // We are already using the last version of the backup + callback.onSuccess(true) + } else { + // We are not using the last version, so delete the current version we are using on the server + callback.onSuccess(false) - // This will automatically check for the last version then - deleteBackup(localBackupVersion, null) + // This will automatically check for the last version then + deleteBackup(localBackupVersion, null) + } } } } @@ -954,9 +955,9 @@ internal class DefaultKeysBackupService @Inject constructor( keysBackupVersion = null keysBackupStateManager.state = KeysBackupState.CheckingBackUpOnHomeserver - getCurrentVersion(object : MatrixCallback<KeysVersionResult?> { - override fun onSuccess(data: KeysVersionResult?) { - checkAndStartWithKeysBackupVersion(data) + getCurrentVersion(object : MatrixCallback<KeysBackupLastVersionResult> { + override fun onSuccess(data: KeysBackupLastVersionResult) { + checkAndStartWithKeysBackupVersion(data.toKeysVersionResult()) } override fun onFailure(failure: Throwable) { @@ -1104,6 +1105,13 @@ internal class DefaultKeysBackupService @Inject constructor( } } + override fun computePrivateKey(passphrase: String, + privateKeySalt: String, + privateKeyIterations: Int, + progressListener: ProgressListener): ByteArray { + return deriveKey(passphrase, privateKeySalt, privateKeyIterations, progressListener) + } + /** * Enable backing up of keys. * This method will update the state and will start sending keys in nominal case diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPassword.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPassword.kt index 24c3942055..c12879dbee 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPassword.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/KeysBackupPassword.kt @@ -30,13 +30,14 @@ import kotlin.experimental.xor private const val SALT_LENGTH = 32 private const val DEFAULT_ITERATION = 500_000 -data class GeneratePrivateKeyResult( +internal data class GeneratePrivateKeyResult( // The private key val privateKey: ByteArray, // the salt used to generate the private key val salt: String, // number of key derivations done on the generated private key. - val iterations: Int) + val iterations: Int +) /** * Compute a private key from a password. @@ -46,7 +47,9 @@ data class GeneratePrivateKeyResult( * @return a {privateKey, salt, iterations} tuple. */ @WorkerThread -fun generatePrivateKeyWithPassword(password: String, progressListener: ProgressListener?): GeneratePrivateKeyResult { +internal fun generatePrivateKeyWithPassword(password: String, + progressListener: ProgressListener? +): GeneratePrivateKeyResult { val salt = generateSalt() val iterations = DEFAULT_ITERATION val privateKey = deriveKey(password, salt, iterations, progressListener) @@ -65,10 +68,10 @@ fun generatePrivateKeyWithPassword(password: String, progressListener: ProgressL * @return a private key. */ @WorkerThread -fun retrievePrivateKeyWithPassword(password: String, - salt: String, - iterations: Int, - progressListener: ProgressListener? = null): ByteArray { +internal fun retrievePrivateKeyWithPassword(password: String, + salt: String, + iterations: Int, + progressListener: ProgressListener? = null): ByteArray { return deriveKey(password, salt, iterations, progressListener) } @@ -83,10 +86,10 @@ fun retrievePrivateKeyWithPassword(password: String, * @return a private key. */ @WorkerThread -fun deriveKey(password: String, - salt: String, - iterations: Int, - progressListener: ProgressListener?): ByteArray { +internal fun deriveKey(password: String, + salt: String, + iterations: Int, + progressListener: ProgressListener?): ByteArray { // Note: copied and adapted from MXMegolmExportEncryption val t0 = System.currentTimeMillis() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/api/RoomKeysApi.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/api/RoomKeysApi.kt index eb4c55a3e7..8464b33526 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/api/RoomKeysApi.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/api/RoomKeysApi.kt @@ -16,12 +16,12 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.api +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersion +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.BackupKeysResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeyBackupData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysBackupData -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.RoomKeysBackupData import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.UpdateKeysBackupVersionBody import org.matrix.android.sdk.internal.network.NetworkConstants diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeyBackupVersionTrust.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeyBackupVersionTrust.kt deleted file mode 100644 index 07ca87fe33..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeyBackupVersionTrust.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.crypto.keysbackup.model - -import com.squareup.moshi.JsonClass - -/** - * Data model for response to [KeysBackup.isKeyBackupTrusted()]. - */ -@JsonClass(generateAdapter = true) -data class KeyBackupVersionTrust( - /** - * Flag to indicate if the backup is trusted. - * true if there is a signature that is valid & from a trusted device. - */ - var usable: Boolean = false, - - /** - * Signatures found in the backup version. - */ - var signatures: MutableList<KeyBackupVersionTrustSignature> = ArrayList() -) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeyBackupVersionTrustSignature.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/SignalableMegolmBackupAuthData.kt similarity index 56% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeyBackupVersionTrustSignature.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/SignalableMegolmBackupAuthData.kt index 5256c78176..85f75a61e2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/KeyBackupVersionTrustSignature.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/SignalableMegolmBackupAuthData.kt @@ -16,20 +16,21 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.model -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.util.JsonDict -/** - * A signature in a the `KeyBackupVersionTrust` object. - */ -class KeyBackupVersionTrustSignature { +internal data class SignalableMegolmBackupAuthData( + val publicKey: String, + val privateKeySalt: String? = null, + val privateKeyIterations: Int? = null +) { + fun signalableJSONDictionary(): JsonDict = HashMap<String, Any>().apply { + put("public_key", publicKey) - /** - * The device that signed the backup version. - */ - var device: CryptoDeviceInfo? = null - - /** - *Flag to indicate the signature from this device is valid. - */ - var valid = false + privateKeySalt?.let { + put("private_key_salt", it) + } + privateKeyIterations?.let { + put("private_key_iterations", it) + } + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeyBackupData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeyBackupData.kt index 3f8129b8f6..5c3d0c12b0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeyBackupData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeyBackupData.kt @@ -25,7 +25,7 @@ import org.matrix.android.sdk.internal.network.parsing.ForceToBoolean * Backup data for one key. */ @JsonClass(generateAdapter = true) -data class KeyBackupData( +internal data class KeyBackupData( /** * Required. The index of the first message in the session that the key can decrypt. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysAlgorithmAndData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysAlgorithmAndData.kt index e098aa0440..898b357c51 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysAlgorithmAndData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysAlgorithmAndData.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.model.rest +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP +import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupAuthData import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM_BACKUP -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupAuthData import org.matrix.android.sdk.internal.di.MoshiProvider /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysBackupData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysBackupData.kt index 6b55f20020..4237458859 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysBackupData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/KeysBackupData.kt @@ -23,7 +23,7 @@ import com.squareup.moshi.JsonClass * Backup data for several keys in several rooms. */ @JsonClass(generateAdapter = true) -data class KeysBackupData( +internal data class KeysBackupData( // the keys are the room IDs, and the values are RoomKeysBackupData @Json(name = "rooms") val roomIdToRoomKeysBackupData: MutableMap<String, RoomKeysBackupData> = HashMap() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/RoomKeysBackupData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/RoomKeysBackupData.kt index ce42a3bc35..5ea6a2f890 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/RoomKeysBackupData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/RoomKeysBackupData.kt @@ -23,7 +23,7 @@ import com.squareup.moshi.JsonClass * Backup data for several keys within a room. */ @JsonClass(generateAdapter = true) -data class RoomKeysBackupData( +internal data class RoomKeysBackupData( // the keys are the session IDs, and the values are KeyBackupData @Json(name = "sessions") val sessionIdToKeyBackupData: MutableMap<String, KeyBackupData> = HashMap() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/UpdateKeysBackupVersionBody.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/UpdateKeysBackupVersionBody.kt index 4512ed7a55..3f2def84d5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/UpdateKeysBackupVersionBody.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/model/rest/UpdateKeysBackupVersionBody.kt @@ -21,7 +21,7 @@ import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.util.JsonDict @JsonClass(generateAdapter = true) -data class UpdateKeysBackupVersionBody( +internal data class UpdateKeysBackupVersionBody( /** * The algorithm used for storing backups. Currently, only "m.megolm_backup.v1.curve25519-aes-sha2" is defined */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/CreateKeysBackupVersionTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/CreateKeysBackupVersionTask.kt index 62610a0b7b..10d6e923e7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/CreateKeysBackupVersionTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/CreateKeysBackupVersionTask.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.tasks +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersion import org.matrix.android.sdk.internal.crypto.keysbackup.api.RoomKeysApi import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.CreateKeysBackupVersionBody -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupLastVersionTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupLastVersionTask.kt index 54dbf85e30..e5621c0cb5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupLastVersionTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupLastVersionTask.kt @@ -16,23 +16,34 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.tasks +import org.matrix.android.sdk.api.failure.is404 +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.api.RoomKeysApi -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task import javax.inject.Inject -internal interface GetKeysBackupLastVersionTask : Task<Unit, KeysVersionResult> +internal interface GetKeysBackupLastVersionTask : Task<Unit, KeysBackupLastVersionResult> internal class DefaultGetKeysBackupLastVersionTask @Inject constructor( private val roomKeysApi: RoomKeysApi, private val globalErrorReceiver: GlobalErrorReceiver ) : GetKeysBackupLastVersionTask { - override suspend fun execute(params: Unit): KeysVersionResult { - return executeRequest(globalErrorReceiver) { - roomKeysApi.getKeysBackupLastVersion() + override suspend fun execute(params: Unit): KeysBackupLastVersionResult { + return try { + val keysVersionResult = executeRequest(globalErrorReceiver) { + roomKeysApi.getKeysBackupLastVersion() + } + KeysBackupLastVersionResult.KeysBackup(keysVersionResult) + } catch (throwable: Throwable) { + if (throwable.is404()) { + KeysBackupLastVersionResult.NoKeysBackup + } else { + // Propagate other errors + throw throwable + } } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupVersionTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupVersionTask.kt index 390873eb68..fe1ca29798 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupVersionTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/tasks/GetKeysBackupVersionTask.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.crypto.keysbackup.tasks +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersionResult import org.matrix.android.sdk.internal.crypto.keysbackup.api.RoomKeysApi -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/Base58.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/Base58.kt index def9c1b675..0e746f289b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/Base58.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/Base58.kt @@ -41,7 +41,7 @@ private val BASE = BigInteger.valueOf(58) /** * Encode a byte array to a human readable string with base58 chars */ -fun base58encode(input: ByteArray): String { +internal fun base58encode(input: ByteArray): String { var bi = BigInteger(1, input) val s = StringBuffer() while (bi >= BASE) { @@ -64,7 +64,7 @@ fun base58encode(input: ByteArray): String { /** * Decode a base58 String to a byte array */ -fun base58decode(input: String): ByteArray { +internal fun base58decode(input: String): ByteArray { var result = decodeToBigInteger(input).toByteArray() // Remove the first leading zero if any diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoDeviceInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoDeviceInfo.kt index b3638dc414..727f739866 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoDeviceInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoDeviceInfo.kt @@ -15,64 +15,8 @@ */ package org.matrix.android.sdk.internal.crypto.model -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DeviceKeys -import org.matrix.android.sdk.internal.crypto.model.rest.UnsignedDeviceInfo - -data class CryptoDeviceInfo( - val deviceId: String, - override val userId: String, - var algorithms: List<String>? = null, - override val keys: Map<String, String>? = null, - override val signatures: Map<String, Map<String, String>>? = null, - val unsigned: UnsignedDeviceInfo? = null, - var trustLevel: DeviceTrustLevel? = null, - var isBlocked: Boolean = false, - val firstTimeSeenLocalTs: Long? = null -) : CryptoInfo { - - val isVerified: Boolean - get() = trustLevel?.isVerified() == true - - val isUnknown: Boolean - get() = trustLevel == null - - /** - * @return the fingerprint - */ - fun fingerprint(): String? { - return keys - ?.takeIf { deviceId.isNotBlank() } - ?.get("ed25519:$deviceId") - } - - /** - * @return the identity key - */ - fun identityKey(): String? { - return keys - ?.takeIf { deviceId.isNotBlank() } - ?.get("curve25519:$deviceId") - } - - /** - * @return the display name - */ - fun displayName(): String? { - return unsigned?.deviceDisplayName - } - - override fun signalableJSONDictionary(): Map<String, Any> { - val map = HashMap<String, Any>() - map["device_id"] = deviceId - map["user_id"] = userId - algorithms?.let { map["algorithms"] = it } - keys?.let { map["keys"] = it } - return map - } - - fun shortDebugString() = "$userId|$deviceId" -} internal fun CryptoDeviceInfo.toRest(): DeviceKeys { return CryptoInfoMapper.map(this) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoInfo.kt index 39981e01f7..e49f17262c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoInfo.kt @@ -20,7 +20,7 @@ package org.matrix.android.sdk.internal.crypto.model * Generic crypto info. * Can be a device (CryptoDeviceInfo), as well as a CryptoCrossSigningInfo (can be seen as a kind of virtual device) */ -interface CryptoInfo { +internal interface CryptoInfo { val userId: String diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoInfoMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoInfoMapper.kt index 6cc6f5400f..de9b3f24ff 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoInfoMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/CryptoInfoMapper.kt @@ -15,6 +15,8 @@ */ package org.matrix.android.sdk.internal.crypto.model +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.rest.DeviceKeys import org.matrix.android.sdk.internal.crypto.model.rest.DeviceKeysWithUnsigned import org.matrix.android.sdk.internal.crypto.model.rest.RestKeyInfo diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXKey.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXKey.kt index 9f425eee7f..cff713bf8f 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXKey.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXKey.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.crypto.model import org.matrix.android.sdk.api.util.JsonDict import timber.log.Timber -data class MXKey( +internal data class MXKey( /** * The type of the key (in the example: "signed_curve25519"). */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXOlmSessionResult.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXOlmSessionResult.kt index b07a08c30f..671827799e 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXOlmSessionResult.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXOlmSessionResult.kt @@ -16,9 +16,10 @@ package org.matrix.android.sdk.internal.crypto.model +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import java.io.Serializable -data class MXOlmSessionResult( +internal data class MXOlmSessionResult( /** * the device */ @@ -27,4 +28,5 @@ data class MXOlmSessionResult( * Base64 olm session id. * null if no session could be established. */ - var sessionId: String?) : Serializable + var sessionId: String? +) : Serializable diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXUsersDevicesMap.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXUsersDevicesMap.kt index bdb00dce8e..58aff14a3d 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXUsersDevicesMap.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/MXUsersDevicesMap.kt @@ -16,119 +16,7 @@ package org.matrix.android.sdk.internal.crypto.model -class MXUsersDevicesMap<E> { - - // A map of maps (userId -> (deviceId -> Object)). - val map = HashMap<String /* userId */, HashMap<String /* deviceId */, E>>() - - /** - * @return the user Ids - */ - val userIds: List<String> - get() = map.keys.toList() - - val isEmpty: Boolean - get() = map.isEmpty() - - /** - * Provides the device ids list for a user id - * FIXME Should maybe return emptyList and not null, to avoid many !! in the code - * - * @param userId the user id - * @return the device ids list - */ - fun getUserDeviceIds(userId: String?): List<String>? { - return if (!userId.isNullOrBlank() && map.containsKey(userId)) { - map[userId]!!.keys.toList() - } else null - } - - /** - * Provides the object for a device id and a user Id - * - * @param deviceId the device id - * @param userId the object id - * @return the object - */ - fun getObject(userId: String?, deviceId: String?): E? { - return if (!userId.isNullOrBlank() && !deviceId.isNullOrBlank()) { - map[userId]?.get(deviceId) - } else null - } - - /** - * Set an object for a dedicated user Id and device Id - * - * @param userId the user Id - * @param deviceId the device id - * @param o the object to set - */ - fun setObject(userId: String?, deviceId: String?, o: E?) { - if (null != o && userId?.isNotBlank() == true && deviceId?.isNotBlank() == true) { - val devices = map.getOrPut(userId) { HashMap() } - devices[deviceId] = o - } - } - - /** - * Defines the objects map for a user Id - * - * @param objectsPerDevices the objects maps - * @param userId the user id - */ - fun setObjects(userId: String?, objectsPerDevices: Map<String, E>?) { - if (!userId.isNullOrBlank()) { - if (null == objectsPerDevices) { - map.remove(userId) - } else { - map[userId] = HashMap(objectsPerDevices) - } - } - } - - /** - * Removes objects for a dedicated user - * - * @param userId the user id. - */ - fun removeUserObjects(userId: String?) { - if (!userId.isNullOrBlank()) { - map.remove(userId) - } - } - - /** - * Clear the internal dictionary - */ - fun removeAllObjects() { - map.clear() - } - - /** - * Add entries from another MXUsersDevicesMap - * - * @param other the other one - */ - fun addEntriesFromMap(other: MXUsersDevicesMap<E>?) { - if (null != other) { - map.putAll(other.map) - } - } - - override fun toString(): String { - return "MXUsersDevicesMap $map" - } -} - -inline fun <T> MXUsersDevicesMap<T>.forEach(action: (String, String, T) -> Unit) { - userIds.forEach { userId -> - getUserDeviceIds(userId)?.forEach { deviceId -> - getObject(userId, deviceId)?.let { - action(userId, deviceId, it) - } - } - } -} +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap internal fun <T> MXUsersDevicesMap<T>.toDebugString() = map.entries.joinToString { "${it.key} [${it.value.keys.joinToString { it }}]" } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper.kt index 086a236a2b..45ffcc6606 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.internal.crypto.model -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.crypto.MegolmSessionData import org.matrix.olm.OlmInboundGroupSession import timber.log.Timber @@ -26,7 +26,7 @@ import java.io.Serializable * This class adds more context to a OlmInboundGroupSession object. * This allows additional checks. The class implements Serializable so that the context can be stored. */ -class OlmInboundGroupSessionWrapper : Serializable { +internal class OlmInboundGroupSessionWrapper : Serializable { // The associated olm inbound group session. var olmInboundGroupSession: OlmInboundGroupSession? = null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt index 1dc27c75ca..1f671aa896 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmInboundGroupSessionWrapper2.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.internal.crypto.model -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.crypto.MegolmSessionData import org.matrix.olm.OlmInboundGroupSession import timber.log.Timber @@ -26,7 +26,7 @@ import java.io.Serializable * This class adds more context to a OlmInboundGroupSession object. * This allows additional checks. The class implements Serializable so that the context can be stored. */ -class OlmInboundGroupSessionWrapper2 : Serializable { +internal class OlmInboundGroupSessionWrapper2 : Serializable { // The associated olm inbound group session. var olmInboundGroupSession: OlmInboundGroupSession? = null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmSessionWrapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmSessionWrapper.kt index 263cb3b036..927d049eca 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmSessionWrapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OlmSessionWrapper.kt @@ -22,7 +22,7 @@ import org.matrix.olm.OlmSession /** * Encapsulate a OlmSession and a last received message Timestamp */ -data class OlmSessionWrapper( +internal data class OlmSessionWrapper( // The associated olm session. val olmSession: OlmSession, // Timestamp at which the session last received a message. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OutboundGroupSessionWrapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OutboundGroupSessionWrapper.kt index b616284e14..4ac87f44ce 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OutboundGroupSessionWrapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/OutboundGroupSessionWrapper.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.internal.crypto.model import org.matrix.olm.OlmOutboundGroupSession -data class OutboundGroupSessionWrapper( +internal data class OutboundGroupSessionWrapper( val outboundGroupSession: OlmOutboundGroupSession, val creationTime: Long ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceKeys.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceKeys.kt index 3a845b1f2a..611d9b72b5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceKeys.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceKeys.kt @@ -20,7 +20,7 @@ import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -data class DeviceKeys( +internal data class DeviceKeys( /** * Required. The ID of the user the device belongs to. Must match the user ID used when logging in. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceKeysWithUnsigned.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceKeysWithUnsigned.kt index 35fce32394..32f577c99b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceKeysWithUnsigned.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/DeviceKeysWithUnsigned.kt @@ -18,9 +18,10 @@ package org.matrix.android.sdk.internal.crypto.model.rest import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.UnsignedDeviceInfo @JsonClass(generateAdapter = true) -data class DeviceKeysWithUnsigned( +internal data class DeviceKeysWithUnsigned( /** * Required. The ID of the user the device belongs to. Must match the user ID used when logging in. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedMessage.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedMessage.kt index f32676a919..c2f76f9dea 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedMessage.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/EncryptedMessage.kt @@ -18,9 +18,10 @@ package org.matrix.android.sdk.internal.crypto.model.rest import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.SendToDeviceObject @JsonClass(generateAdapter = true) -data class EncryptedMessage( +internal data class EncryptedMessage( @Json(name = "algorithm") val algorithm: String? = null, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/GossipingDefaultContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/GossipingDefaultContent.kt new file mode 100644 index 0000000000..8f789a638c --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/GossipingDefaultContent.kt @@ -0,0 +1,27 @@ +/* + * Copyright 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.matrix.android.sdk.internal.crypto.model.rest + +import com.squareup.moshi.Json +import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.GossipingToDeviceObject + +@JsonClass(generateAdapter = true) +internal data class GossipingDefaultContent( + @Json(name = "action") override val action: String?, + @Json(name = "requesting_device_id") override val requestingDeviceId: String?, + @Json(name = "m.request_id") override val requestId: String? = null +) : GossipingToDeviceObject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationAccept.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationAccept.kt index f695425c2a..7a5773bf24 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationAccept.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationAccept.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.crypto.model.rest import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.SendToDeviceObject import org.matrix.android.sdk.internal.crypto.verification.VerificationInfoAccept import org.matrix.android.sdk.internal.crypto.verification.VerificationInfoAcceptFactory diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationCancel.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationCancel.kt index 4dfa5984df..90272bf0e4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationCancel.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationCancel.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.crypto.model.rest import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.SendToDeviceObject import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.internal.crypto.verification.VerificationInfoCancel diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationDone.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationDone.kt index 96afba060b..e3907914ac 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationDone.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationDone.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.crypto.model.rest import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.SendToDeviceObject import org.matrix.android.sdk.internal.crypto.verification.VerificationInfoDone /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationKey.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationKey.kt index 7ded437cea..19d8c32ddf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationKey.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationKey.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.crypto.model.rest import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.SendToDeviceObject import org.matrix.android.sdk.internal.crypto.verification.VerificationInfoKey import org.matrix.android.sdk.internal.crypto.verification.VerificationInfoKeyFactory diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationMac.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationMac.kt index 6c055aee2a..5335428c0f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationMac.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationMac.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.crypto.model.rest import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.SendToDeviceObject import org.matrix.android.sdk.internal.crypto.verification.VerificationInfoMac import org.matrix.android.sdk.internal.crypto.verification.VerificationInfoMacFactory diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationReady.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationReady.kt index 3562613c2e..e6770be9a0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationReady.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationReady.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.crypto.model.rest import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.SendToDeviceObject import org.matrix.android.sdk.internal.crypto.verification.VerificationInfoReady /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationRequest.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationRequest.kt index c30b2a306f..191d5abb60 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationRequest.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationRequest.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.crypto.model.rest import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.SendToDeviceObject import org.matrix.android.sdk.internal.crypto.verification.VerificationInfoRequest /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationStart.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationStart.kt index 52a66a9db6..f74bad844d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationStart.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/KeyVerificationStart.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.crypto.model.rest import com.squareup.moshi.Json import com.squareup.moshi.JsonClass +import org.matrix.android.sdk.api.session.crypto.model.SendToDeviceObject import org.matrix.android.sdk.internal.crypto.verification.VerificationInfoStart import org.matrix.android.sdk.internal.util.JsonCanonicalizer diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/RestKeyInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/RestKeyInfo.kt index 0d41e5b648..66247d07d1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/RestKeyInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/RestKeyInfo.kt @@ -17,7 +17,7 @@ package org.matrix.android.sdk.internal.crypto.model.rest import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey import org.matrix.android.sdk.internal.crypto.model.CryptoInfoMapper @JsonClass(generateAdapter = true) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/ShareRequestCancellation.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/ShareRequestCancellation.kt index 820ff69746..a96534fc3a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/ShareRequestCancellation.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/ShareRequestCancellation.kt @@ -17,7 +17,8 @@ package org.matrix.android.sdk.internal.crypto.model.rest import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.internal.crypto.model.rest.GossipingToDeviceObject.Companion.ACTION_SHARE_CANCELLATION +import org.matrix.android.sdk.api.session.crypto.model.GossipingToDeviceObject +import org.matrix.android.sdk.api.session.crypto.model.GossipingToDeviceObject.Companion.ACTION_SHARE_CANCELLATION /** * Class representing a room key request cancellation content diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/UploadSignatureQueryBuilder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/UploadSignatureQueryBuilder.kt index 1347c2f4b6..dd0ce47cd3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/UploadSignatureQueryBuilder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/model/rest/UploadSignatureQueryBuilder.kt @@ -15,8 +15,9 @@ */ package org.matrix.android.sdk.internal.crypto.model.rest -import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey +import org.matrix.android.sdk.api.session.crypto.crosssigning.toRest +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.internal.crypto.model.toRest /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt index e6d8b5e84f..19e66635c7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/secrets/DefaultSharedSecretStorageService.kt @@ -19,9 +19,12 @@ package org.matrix.android.sdk.internal.crypto.secrets import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.MatrixCoroutineDispatchers +import org.matrix.android.sdk.api.crypto.SSSS_ALGORITHM_AES_HMAC_SHA2 +import org.matrix.android.sdk.api.crypto.SSSS_ALGORITHM_CURVE25519_AES_SHA2 import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.accountdata.SessionAccountDataService +import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.securestorage.EncryptedSecretContent import org.matrix.android.sdk.api.session.securestorage.IntegrityResult @@ -35,13 +38,10 @@ import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageServi import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo import org.matrix.android.sdk.api.session.securestorage.SsssKeySpec import org.matrix.android.sdk.api.session.securestorage.SsssPassphrase +import org.matrix.android.sdk.api.util.fromBase64 +import org.matrix.android.sdk.api.util.toBase64NoPadding import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager -import org.matrix.android.sdk.internal.crypto.SSSS_ALGORITHM_AES_HMAC_SHA2 -import org.matrix.android.sdk.internal.crypto.SSSS_ALGORITHM_CURVE25519_AES_SHA2 -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding import org.matrix.android.sdk.internal.crypto.keysbackup.generatePrivateKeyWithPassword -import org.matrix.android.sdk.internal.crypto.keysbackup.util.computeRecoveryKey import org.matrix.android.sdk.internal.crypto.tools.HkdfSha256 import org.matrix.android.sdk.internal.crypto.tools.withOlmDecryption import org.matrix.android.sdk.internal.di.UserId diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt index e662ff74e7..8bedb78808 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/IMXCryptoStore.kt @@ -18,25 +18,27 @@ package org.matrix.android.sdk.internal.crypto.store import androidx.lifecycle.LiveData import androidx.paging.PagedList +import org.matrix.android.sdk.api.session.crypto.NewSessionListener +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.PrivateKeysInfo +import org.matrix.android.sdk.api.session.crypto.keysbackup.SavedKeyBackupKeyInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.GossipingRequestState +import org.matrix.android.sdk.api.session.crypto.model.IncomingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.api.session.crypto.model.OutgoingGossipingRequestState +import org.matrix.android.sdk.api.session.crypto.model.OutgoingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent import org.matrix.android.sdk.api.util.Optional -import org.matrix.android.sdk.internal.crypto.GossipingRequestState -import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest import org.matrix.android.sdk.internal.crypto.IncomingShareRequestCommon -import org.matrix.android.sdk.internal.crypto.NewSessionListener -import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestState -import org.matrix.android.sdk.internal.crypto.OutgoingRoomKeyRequest import org.matrix.android.sdk.internal.crypto.OutgoingSecretRequest -import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper2 import org.matrix.android.sdk.internal.crypto.model.OlmSessionWrapper import org.matrix.android.sdk.internal.crypto.model.OutboundGroupSessionWrapper -import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntity import org.matrix.olm.OlmAccount import org.matrix.olm.OlmOutboundGroupSession diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt index 493e7fbc39..b841e9c6e5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/Helper.kt @@ -28,7 +28,7 @@ import java.util.zip.GZIPOutputStream /** * Get realm, invoke the action, close realm, and return the result of the action */ -fun <T> doWithRealm(realmConfiguration: RealmConfiguration, action: (Realm) -> T): T { +internal fun <T> doWithRealm(realmConfiguration: RealmConfiguration, action: (Realm) -> T): T { return Realm.getInstance(realmConfiguration).use { realm -> action.invoke(realm) } @@ -37,7 +37,7 @@ fun <T> doWithRealm(realmConfiguration: RealmConfiguration, action: (Realm) -> T /** * Get realm, do the query, copy from realm, close realm, and return the copied result */ -fun <T : RealmObject> doRealmQueryAndCopy(realmConfiguration: RealmConfiguration, action: (Realm) -> T?): T? { +internal fun <T : RealmObject> doRealmQueryAndCopy(realmConfiguration: RealmConfiguration, action: (Realm) -> T?): T? { return Realm.getInstance(realmConfiguration).use { realm -> action.invoke(realm)?.let { realm.copyFromRealm(it) } } @@ -46,7 +46,7 @@ fun <T : RealmObject> doRealmQueryAndCopy(realmConfiguration: RealmConfiguration /** * Get realm, do the list query, copy from realm, close realm, and return the copied result */ -fun <T : RealmObject> doRealmQueryAndCopyList(realmConfiguration: RealmConfiguration, action: (Realm) -> Iterable<T>): Iterable<T> { +internal fun <T : RealmObject> doRealmQueryAndCopyList(realmConfiguration: RealmConfiguration, action: (Realm) -> Iterable<T>): Iterable<T> { return Realm.getInstance(realmConfiguration).use { realm -> action.invoke(realm).let { realm.copyFromRealm(it) } } @@ -55,13 +55,13 @@ fun <T : RealmObject> doRealmQueryAndCopyList(realmConfiguration: RealmConfigura /** * Get realm instance, invoke the action in a transaction and close realm */ -fun doRealmTransaction(realmConfiguration: RealmConfiguration, action: (Realm) -> Unit) { +internal fun doRealmTransaction(realmConfiguration: RealmConfiguration, action: (Realm) -> Unit) { Realm.getInstance(realmConfiguration).use { realm -> realm.executeTransaction { action.invoke(it) } } } -fun doRealmTransactionAsync(realmConfiguration: RealmConfiguration, action: (Realm) -> Unit) { +internal fun doRealmTransactionAsync(realmConfiguration: RealmConfiguration, action: (Realm) -> Unit) { Realm.getInstance(realmConfiguration).use { realm -> realm.executeTransactionAsync { action.invoke(it) } } @@ -70,7 +70,7 @@ fun doRealmTransactionAsync(realmConfiguration: RealmConfiguration, action: (Rea /** * Serialize any Serializable object, zip it and convert to Base64 String */ -fun serializeForRealm(o: Any?): String? { +internal fun serializeForRealm(o: Any?): String? { if (o == null) { return null } @@ -88,7 +88,7 @@ fun serializeForRealm(o: Any?): String? { * Do the opposite of serializeForRealm. */ @Suppress("UNCHECKED_CAST") -fun <T> deserializeFromRealm(string: String?): T? { +internal fun <T> deserializeFromRealm(string: String?): T? { if (string == null) { return null } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt index 14c1741a34..2b22c1fda4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/RealmCryptoStore.kt @@ -25,35 +25,35 @@ import io.realm.Realm import io.realm.RealmConfiguration import io.realm.Sort import io.realm.kotlin.where +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.session.crypto.NewSessionListener +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.PrivateKeysInfo +import org.matrix.android.sdk.api.session.crypto.keysbackup.SavedKeyBackupKeyInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.GossipingRequestState +import org.matrix.android.sdk.api.session.crypto.model.IncomingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.IncomingSecretShareRequest +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult +import org.matrix.android.sdk.api.session.crypto.model.OutgoingGossipingRequestState +import org.matrix.android.sdk.api.session.crypto.model.OutgoingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.content.RoomKeyWithHeldContent import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.internal.crypto.GossipRequestType -import org.matrix.android.sdk.internal.crypto.GossipingRequestState -import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest -import org.matrix.android.sdk.internal.crypto.IncomingSecretShareRequest import org.matrix.android.sdk.internal.crypto.IncomingShareRequestCommon -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.NewSessionListener -import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestState -import org.matrix.android.sdk.internal.crypto.OutgoingRoomKeyRequest import org.matrix.android.sdk.internal.crypto.OutgoingSecretRequest -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult -import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.OlmInboundGroupSessionWrapper2 import org.matrix.android.sdk.internal.crypto.model.OlmSessionWrapper import org.matrix.android.sdk.internal.crypto.model.OutboundGroupSessionWrapper -import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore -import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo -import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo import org.matrix.android.sdk.internal.crypto.store.db.mapper.CrossSigningKeysMapper import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntity import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntityFields diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt index c15414a8dd..5e4b9b96da 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/mapper/CrossSigningKeysMapper.kt @@ -19,8 +19,8 @@ package org.matrix.android.sdk.internal.crypto.store.db.mapper import com.squareup.moshi.Moshi import com.squareup.moshi.Types import io.realm.RealmList -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.internal.crypto.store.db.model.KeyInfoEntity import timber.log.Timber import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo001Legacy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo001Legacy.kt index 0e44689428..7dee42e51a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo001Legacy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo001Legacy.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntityFie import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber -class MigrateCryptoTo001Legacy(realm: DynamicRealm) : RealmMigrator(realm, 1) { +internal class MigrateCryptoTo001Legacy(realm: DynamicRealm) : RealmMigrator(realm, 1) { override fun doMigrate(realm: DynamicRealm) { Timber.d("Add field lastReceivedMessageTs (Long) and set the value to 0") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo002Legacy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo002Legacy.kt index 84e627a688..1b53e1928a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo002Legacy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo002Legacy.kt @@ -22,7 +22,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.KeysBackupDataEntit import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber -class MigrateCryptoTo002Legacy(realm: DynamicRealm) : RealmMigrator(realm, 2) { +internal class MigrateCryptoTo002Legacy(realm: DynamicRealm) : RealmMigrator(realm, 2) { override fun doMigrate(realm: DynamicRealm) { Timber.d("Update IncomingRoomKeyRequestEntity format: requestBodyString field is exploded into several fields") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo003RiotX.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo003RiotX.kt index b468a56af6..34d1afa2d8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo003RiotX.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo003RiotX.kt @@ -26,7 +26,7 @@ import org.matrix.androidsdk.crypto.data.MXDeviceInfo import org.matrix.androidsdk.crypto.data.MXOlmInboundGroupSession2 import timber.log.Timber -class MigrateCryptoTo003RiotX(realm: DynamicRealm) : RealmMigrator(realm, 3) { +internal class MigrateCryptoTo003RiotX(realm: DynamicRealm) : RealmMigrator(realm, 3) { override fun doMigrate(realm: DynamicRealm) { Timber.d("Migrate to RiotX model") @@ -40,7 +40,7 @@ class MigrateCryptoTo003RiotX(realm: DynamicRealm) : RealmMigrator(realm, 3) { try { val oldSerializedData = obj.getString("deviceInfoData") deserializeFromRealm<MXDeviceInfo>(oldSerializedData)?.let { legacyMxDeviceInfo -> - val newMxDeviceInfo = org.matrix.android.sdk.internal.crypto.model.MXDeviceInfo( + val newMxDeviceInfo = org.matrix.android.sdk.api.session.crypto.model.MXDeviceInfo( deviceId = legacyMxDeviceInfo.deviceId, userId = legacyMxDeviceInfo.userId, algorithms = legacyMxDeviceInfo.algorithms, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo004.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo004.kt index 20a4814b8d..52d0124c2b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo004.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo004.kt @@ -19,8 +19,8 @@ package org.matrix.android.sdk.internal.crypto.store.db.migration import com.squareup.moshi.Moshi import com.squareup.moshi.Types import io.realm.DynamicRealm +import org.matrix.android.sdk.api.session.crypto.model.MXDeviceInfo import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.crypto.model.MXDeviceInfo import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm import org.matrix.android.sdk.internal.crypto.store.db.model.CrossSigningInfoEntityFields import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntityFields @@ -33,7 +33,7 @@ import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber // Version 4L added Cross Signing info persistence -class MigrateCryptoTo004(realm: DynamicRealm) : RealmMigrator(realm, 4) { +internal class MigrateCryptoTo004(realm: DynamicRealm) : RealmMigrator(realm, 4) { override fun doMigrate(realm: DynamicRealm) { if (realm.schema.contains("TrustLevelEntity")) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo005.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo005.kt index 8365d34464..e1d7598767 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo005.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo005.kt @@ -22,7 +22,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.IncomingGossipingRe import org.matrix.android.sdk.internal.crypto.store.db.model.OutgoingGossipingRequestEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateCryptoTo005(realm: DynamicRealm) : RealmMigrator(realm, 5) { +internal class MigrateCryptoTo005(realm: DynamicRealm) : RealmMigrator(realm, 5) { override fun doMigrate(realm: DynamicRealm) { realm.schema.remove("OutgoingRoomKeyRequestEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo006.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo006.kt index a29a791826..39b2898514 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo006.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo006.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntit import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber -class MigrateCryptoTo006(realm: DynamicRealm) : RealmMigrator(realm, 6) { +internal class MigrateCryptoTo006(realm: DynamicRealm) : RealmMigrator(realm, 6) { override fun doMigrate(realm: DynamicRealm) { Timber.d("Updating CryptoMetadataEntity table") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo007.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo007.kt index 7ae58e7fc0..718b9787d2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo007.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo007.kt @@ -28,7 +28,7 @@ import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber -class MigrateCryptoTo007(realm: DynamicRealm) : RealmMigrator(realm, 7) { +internal class MigrateCryptoTo007(realm: DynamicRealm) : RealmMigrator(realm, 7) { override fun doMigrate(realm: DynamicRealm) { Timber.d("Updating KeyInfoEntity table") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo008.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo008.kt index e3bd3f035a..785e6a04f4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo008.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo008.kt @@ -22,7 +22,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.DeviceInfoEntityFie import org.matrix.android.sdk.internal.crypto.store.db.model.MyDeviceLastSeenInfoEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateCryptoTo008(realm: DynamicRealm) : RealmMigrator(realm, 8) { +internal class MigrateCryptoTo008(realm: DynamicRealm) : RealmMigrator(realm, 8) { override fun doMigrate(realm: DynamicRealm) { realm.schema.create("MyDeviceLastSeenInfoEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo009.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo009.kt index ed705318f9..8d9d24dfba 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo009.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo009.kt @@ -23,7 +23,7 @@ import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber // Fixes duplicate devices in UserEntity#devices -class MigrateCryptoTo009(realm: DynamicRealm) : RealmMigrator(realm, 9) { +internal class MigrateCryptoTo009(realm: DynamicRealm) : RealmMigrator(realm, 9) { override fun doMigrate(realm: DynamicRealm) { val userEntities = realm.where("UserEntity").findAll() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo010.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo010.kt index 8d69ee5558..faf0d58832 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo010.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo010.kt @@ -22,7 +22,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEnti import org.matrix.android.sdk.internal.util.database.RealmMigrator // Version 10L added WithHeld Keys Info (MSC2399) -class MigrateCryptoTo010(realm: DynamicRealm) : RealmMigrator(realm, 10) { +internal class MigrateCryptoTo010(realm: DynamicRealm) : RealmMigrator(realm, 10) { override fun doMigrate(realm: DynamicRealm) { realm.schema.create("WithHeldSessionEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo011.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo011.kt index c9825a7f3d..feaab4bb19 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo011.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo011.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntit import org.matrix.android.sdk.internal.util.database.RealmMigrator // Version 11L added deviceKeysSentToServer boolean to CryptoMetadataEntity -class MigrateCryptoTo011(realm: DynamicRealm) : RealmMigrator(realm, 11) { +internal class MigrateCryptoTo011(realm: DynamicRealm) : RealmMigrator(realm, 11) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("CryptoMetadataEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo012.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo012.kt index 6b1460d9d6..4626757a06 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo012.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo012.kt @@ -22,7 +22,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.OutboundGroupSessio import org.matrix.android.sdk.internal.util.database.RealmMigrator // Version 12L added outbound group session persistence -class MigrateCryptoTo012(realm: DynamicRealm) : RealmMigrator(realm, 12) { +internal class MigrateCryptoTo012(realm: DynamicRealm) : RealmMigrator(realm, 12) { override fun doMigrate(realm: DynamicRealm) { val outboundEntitySchema = realm.schema.create("OutboundGroupSessionInfoEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo013.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo013.kt index dc22c5f133..dc8984da41 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo013.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo013.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber // Version 13L delete unreferenced TrustLevelEntity -class MigrateCryptoTo013(realm: DynamicRealm) : RealmMigrator(realm, 13) { +internal class MigrateCryptoTo013(realm: DynamicRealm) : RealmMigrator(realm, 13) { override fun doMigrate(realm: DynamicRealm) { // Use a trick to do that... Ref: https://stackoverflow.com/questions/55221366 diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo014.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo014.kt index f0089e3427..548672790a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo014.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo014.kt @@ -22,7 +22,7 @@ import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntity import org.matrix.android.sdk.internal.util.database.RealmMigrator // Version 14L Update the way we remember key sharing -class MigrateCryptoTo014(realm: DynamicRealm) : RealmMigrator(realm, 14) { +internal class MigrateCryptoTo014(realm: DynamicRealm) : RealmMigrator(realm, 14) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("SharedSessionEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt index 465c18555a..bca02c2e6e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/migration/MigrateCryptoTo015.kt @@ -17,12 +17,12 @@ package org.matrix.android.sdk.internal.crypto.store.db.migration import io.realm.DynamicRealm -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoRoomEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator // Version 15L adds wasEncryptedOnce field to CryptoRoomEntity -class MigrateCryptoTo015(realm: DynamicRealm) : RealmMigrator(realm, 15) { +internal class MigrateCryptoTo015(realm: DynamicRealm) : RealmMigrator(realm, 15) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("CryptoRoomEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt index 8599c972e9..5aba9bb9ba 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CrossSigningInfoEntity.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.crypto.store.db.model import io.realm.RealmList import io.realm.RealmObject import io.realm.annotations.PrimaryKey -import org.matrix.android.sdk.internal.crypto.model.KeyUsage +import org.matrix.android.sdk.api.session.crypto.crosssigning.KeyUsage import org.matrix.android.sdk.internal.extensions.clearWith internal open class CrossSigningInfoEntity( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMapper.kt index 7ba986699a..c71d5e73a2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/CryptoMapper.kt @@ -17,14 +17,14 @@ package org.matrix.android.sdk.internal.crypto.store.db.model import com.squareup.moshi.Moshi import com.squareup.moshi.Types +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.UnsignedDeviceInfo import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.UnsignedDeviceInfo import org.matrix.android.sdk.internal.di.SerializeNulls import timber.log.Timber -object CryptoMapper { +internal object CryptoMapper { private val moshi = Moshi.Builder().add(SerializeNulls.JSON_ADAPTER_FACTORY).build() private val listMigrationAdapter = moshi.adapter<List<String>>(Types.newParameterizedType( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/GossipingEventEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/GossipingEventEntity.kt index 75094f01db..a024e092b7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/GossipingEventEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/GossipingEventEntity.kt @@ -20,10 +20,10 @@ import com.squareup.moshi.JsonDataException import io.realm.RealmObject import io.realm.annotations.Index import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.send.SendState -import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.di.MoshiProvider import timber.log.Timber diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/IncomingGossipingRequestEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/IncomingGossipingRequestEntity.kt index 4457a44cb2..f05c8853c8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/IncomingGossipingRequestEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/IncomingGossipingRequestEntity.kt @@ -19,12 +19,12 @@ package org.matrix.android.sdk.internal.crypto.store.db.model import io.realm.RealmObject import io.realm.annotations.Index import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.session.crypto.model.GossipingRequestState +import org.matrix.android.sdk.api.session.crypto.model.IncomingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.IncomingSecretShareRequest +import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.GossipRequestType -import org.matrix.android.sdk.internal.crypto.GossipingRequestState -import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest -import org.matrix.android.sdk.internal.crypto.IncomingSecretShareRequest import org.matrix.android.sdk.internal.crypto.IncomingShareRequestCommon -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody internal open class IncomingGossipingRequestEntity(@Index var requestId: String? = "", @Index var typeStr: String? = null, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutgoingGossipingRequestEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutgoingGossipingRequestEntity.kt index a19547fddc..0e1278967e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutgoingGossipingRequestEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/OutgoingGossipingRequestEntity.kt @@ -21,12 +21,12 @@ import com.squareup.moshi.Types import io.realm.RealmObject import io.realm.annotations.Index import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.session.crypto.model.OutgoingGossipingRequestState +import org.matrix.android.sdk.api.session.crypto.model.OutgoingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.RoomKeyRequestBody import org.matrix.android.sdk.internal.crypto.GossipRequestType import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequest -import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestState -import org.matrix.android.sdk.internal.crypto.OutgoingRoomKeyRequest import org.matrix.android.sdk.internal.crypto.OutgoingSecretRequest -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody import org.matrix.android.sdk.internal.di.MoshiProvider internal open class OutgoingGossipingRequestEntity( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/WithHeldSessionEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/WithHeldSessionEntity.kt index 6d7889053b..93048e5775 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/WithHeldSessionEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/model/WithHeldSessionEntity.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.internal.crypto.store.db.model import io.realm.RealmObject import io.realm.annotations.Index -import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode +import org.matrix.android.sdk.api.session.events.model.content.WithHeldCode /** * When an encrypted message is sent in a room, the megolm key might not be sent to all devices present in the room. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt index 2784e58425..8bf9794375 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/SharedSessionQueries.kt @@ -20,7 +20,7 @@ import io.realm.Realm import io.realm.RealmResults import io.realm.kotlin.createObject import io.realm.kotlin.where -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntity import org.matrix.android.sdk.internal.crypto.store.db.model.SharedSessionEntityFields diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/WithHeldSessionQueries.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/WithHeldSessionQueries.kt index b8a3e36137..c253af2bf6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/WithHeldSessionQueries.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/store/db/query/WithHeldSessionQueries.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.crypto.store.db.query import io.realm.Realm import io.realm.kotlin.createObject import io.realm.kotlin.where -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntity import org.matrix.android.sdk.internal.crypto.store.db.model.WithHeldSessionEntityFields diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/ClaimOneTimeKeysForUsersDeviceTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/ClaimOneTimeKeysForUsersDeviceTask.kt index d5cf749db7..96848a264d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/ClaimOneTimeKeysForUsersDeviceTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/ClaimOneTimeKeysForUsersDeviceTask.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.crypto.tasks +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.api.CryptoApi import org.matrix.android.sdk.internal.crypto.model.MXKey -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.rest.KeysClaimBody import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt index 627352f568..1e395796a9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/EncryptEventTask.kt @@ -15,18 +15,18 @@ */ package org.matrix.android.sdk.internal.crypto.tasks +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.api.session.crypto.CryptoService +import org.matrix.android.sdk.api.session.crypto.model.MXEncryptEventContentResult +import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.room.send.SendState -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult -import org.matrix.android.sdk.internal.crypto.model.MXEncryptEventContentResult +import org.matrix.android.sdk.api.util.awaitCallback import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.session.room.send.LocalEchoRepository import org.matrix.android.sdk.internal.task.Task -import org.matrix.android.sdk.internal.util.awaitCallback import javax.inject.Inject internal interface EncryptEventTask : Task<EncryptEventTask.Params, Event> { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/GetDeviceInfoTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/GetDeviceInfoTask.kt index 9f20ea598d..87dbd8d1a0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/GetDeviceInfoTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/GetDeviceInfoTask.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.crypto.tasks +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo import org.matrix.android.sdk.internal.crypto.api.CryptoApi -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/GetDevicesTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/GetDevicesTask.kt index 52f9f73299..27cb17f2ab 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/GetDevicesTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/GetDevicesTask.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.crypto.tasks +import org.matrix.android.sdk.api.session.crypto.model.DevicesListResponse import org.matrix.android.sdk.internal.crypto.api.CryptoApi -import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt index e2fd54f0d8..eefdd25044 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/InitializeCrossSigningTask.kt @@ -18,13 +18,13 @@ package org.matrix.android.sdk.internal.crypto.tasks import dagger.Lazy import org.matrix.android.sdk.api.auth.UserInteractiveAuthInterceptor +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey +import org.matrix.android.sdk.api.session.crypto.crosssigning.KeyUsage +import org.matrix.android.sdk.api.util.toBase64NoPadding import org.matrix.android.sdk.internal.auth.registration.handleUIA import org.matrix.android.sdk.internal.crypto.MXOlmDevice import org.matrix.android.sdk.internal.crypto.MyDeviceInfoHolder import org.matrix.android.sdk.internal.crypto.crosssigning.canonicalSignable -import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding -import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey -import org.matrix.android.sdk.internal.crypto.model.KeyUsage import org.matrix.android.sdk.internal.crypto.model.rest.UploadSignatureQueryBuilder import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.task.Task diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendToDeviceTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendToDeviceTask.kt index c6af9b0cd1..fc4d422360 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendToDeviceTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/SendToDeviceTask.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.crypto.tasks +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.api.CryptoApi -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.rest.SendToDeviceBody import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSigningKeysTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSigningKeysTask.kt index 6cb14ded63..0a0df11bd3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSigningKeysTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tasks/UploadSigningKeysTask.kt @@ -18,10 +18,10 @@ package org.matrix.android.sdk.internal.crypto.tasks import org.matrix.android.sdk.api.auth.UIABaseAuth import org.matrix.android.sdk.api.failure.Failure +import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey +import org.matrix.android.sdk.api.session.crypto.crosssigning.toRest import org.matrix.android.sdk.internal.crypto.api.CryptoApi -import org.matrix.android.sdk.internal.crypto.model.CryptoCrossSigningKey import org.matrix.android.sdk.internal.crypto.model.rest.UploadSigningKeysBody -import org.matrix.android.sdk.internal.crypto.model.toRest import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.task.Task @@ -42,7 +42,7 @@ internal interface UploadSigningKeysTask : Task<UploadSigningKeysTask.Params, Un ) } -data class UploadSigningKeys(val failures: Map<String, Any>?) : Failure.FeatureFailure() +internal data class UploadSigningKeys(val failures: Map<String, Any>?) : Failure.FeatureFailure() internal class DefaultUploadSigningKeysTask @Inject constructor( private val cryptoApi: CryptoApi, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/HkdfSha256.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/HkdfSha256.kt index 04ce0d8500..b230f0d029 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/HkdfSha256.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/tools/HkdfSha256.kt @@ -26,7 +26,7 @@ import kotlin.math.ceil * HMAC-based Extract-and-Expand Key Derivation Function (HkdfSha256) * [RFC-5869] https://tools.ietf.org/html/rfc5869 */ -object HkdfSha256 { +internal object HkdfSha256 { fun deriveSecret(inputKeyMaterial: ByteArray, salt: ByteArray?, info: ByteArray, outputLength: Int): ByteArray { return expand(extract(salt, inputKeyMaterial), info, outputLength) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt index bd623575fa..28bf1d70f7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationService.kt @@ -23,10 +23,13 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.launch import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest import org.matrix.android.sdk.api.session.crypto.verification.QrCodeVerificationTransaction @@ -41,6 +44,7 @@ import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.LocalEcho import org.matrix.android.sdk.api.session.events.model.RelationType +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent @@ -59,10 +63,6 @@ import org.matrix.android.sdk.internal.crypto.IncomingGossipingRequestManager import org.matrix.android.sdk.internal.crypto.MyDeviceInfoHolder import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationAccept import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationDone diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationTransaction.kt index 6043c21b66..69d9388c5f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/DefaultVerificationTransaction.kt @@ -17,12 +17,12 @@ package org.matrix.android.sdk.internal.crypto.verification import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.session.crypto.crosssigning.CrossSigningService +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState import org.matrix.android.sdk.internal.crypto.IncomingGossipingRequestManager import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel import timber.log.Timber /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfo.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfo.kt index 368a9b6b54..0615773a7b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfo.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfo.kt @@ -15,10 +15,10 @@ */ package org.matrix.android.sdk.internal.crypto.verification +import org.matrix.android.sdk.api.session.crypto.model.SendToDeviceObject import org.matrix.android.sdk.api.session.events.model.Content -import org.matrix.android.sdk.internal.crypto.model.rest.SendToDeviceObject -interface VerificationInfo<ValidObjectType> { +internal interface VerificationInfo<ValidObjectType> { fun toEventContent(): Content? = null fun toSendToDeviceObject(): SendToDeviceObject? = null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt index f727aff39d..40c96dfa95 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationInfoStart.kt @@ -103,7 +103,7 @@ internal interface VerificationInfoStart : VerificationInfo<ValidVerificationInf } } -sealed class ValidVerificationInfoStart( +internal sealed class ValidVerificationInfoStart( open val transactionId: String, open val fromDevice: String) { data class SasVerificationInfoStart( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationMessageProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationMessageProcessor.kt index 4a2a153127..52166761ab 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationMessageProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationMessageProcessor.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.crypto.verification import io.realm.Realm import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType @@ -29,13 +30,11 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageVerification import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationRequestContent import org.matrix.android.sdk.api.session.room.model.message.MessageVerificationStartContent import org.matrix.android.sdk.internal.crypto.EventDecryptor -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.database.model.EventInsertType import org.matrix.android.sdk.internal.di.DeviceId import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor import timber.log.Timber -import java.util.ArrayList import javax.inject.Inject internal class VerificationMessageProcessor @Inject constructor( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationStateExt.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationStateExt.kt index 0617f32c24..d8cba1fffa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationStateExt.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationStateExt.kt @@ -16,8 +16,8 @@ package org.matrix.android.sdk.internal.crypto.verification -import org.matrix.android.sdk.api.crypto.VerificationState -import org.matrix.android.sdk.api.crypto.isCanceled +import org.matrix.android.sdk.api.session.crypto.verification.VerificationState +import org.matrix.android.sdk.api.session.crypto.verification.isCanceled // State transition with control internal fun VerificationState?.toState(newState: VerificationState): VerificationState { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt index 45f8143937..40deda2745 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/VerificationTransportToDevice.kt @@ -16,12 +16,12 @@ package org.matrix.android.sdk.internal.crypto.verification import org.matrix.android.sdk.api.MatrixCallback +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.ValidVerificationInfoRequest import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.room.model.message.MessageType -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationAccept import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationCancel import org.matrix.android.sdk.internal.crypto.model.rest.KeyVerificationDone diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt index 90ede18dc8..06f0b36798 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/DefaultQrCodeVerificationTransaction.kt @@ -21,10 +21,10 @@ import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.QrCodeVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.util.fromBase64 import org.matrix.android.sdk.internal.crypto.IncomingGossipingRequestManager import org.matrix.android.sdk.internal.crypto.OutgoingGossipingRequestManager import org.matrix.android.sdk.internal.crypto.actions.SetDeviceVerificationAction -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64Safe import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationTransaction diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/Extensions.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/Extensions.kt index 76e88442b6..b80c29c244 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/Extensions.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/Extensions.kt @@ -16,14 +16,14 @@ package org.matrix.android.sdk.internal.crypto.verification.qrcode -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding +import org.matrix.android.sdk.api.util.fromBase64 +import org.matrix.android.sdk.api.util.toBase64NoPadding import org.matrix.android.sdk.internal.extensions.toUnsignedInt // MATRIX private val prefix = "MATRIX".toByteArray(Charsets.ISO_8859_1) -fun QrCodeData.toEncodedString(): String { +internal fun QrCodeData.toEncodedString(): String { var result = ByteArray(0) // MATRIX @@ -67,7 +67,7 @@ fun QrCodeData.toEncodedString(): String { return result.toString(Charsets.ISO_8859_1) } -fun String.toQrCodeData(): QrCodeData? { +internal fun String.toQrCodeData(): QrCodeData? { val byteArray = toByteArray(Charsets.ISO_8859_1) // Size should be min 6 + 1 + 1 + 2 + ? + 32 + 32 + ? = 74 + transactionLength + secretLength diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/QrCodeData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/QrCodeData.kt index 25c04efde7..0ac57db9bc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/QrCodeData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/QrCodeData.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.crypto.verification.qrcode /** * Ref: https://github.com/uhoreg/matrix-doc/blob/qr_key_verification/proposals/1543-qr_code_key_verification.md#qr-code-format */ -sealed class QrCodeData( +internal sealed class QrCodeData( /** * the event ID or transaction_id of the associated verification */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecret.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecret.kt index 858c0ab6af..52b09be49c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecret.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/crypto/verification/qrcode/SharedSecret.kt @@ -16,10 +16,10 @@ package org.matrix.android.sdk.internal.crypto.verification.qrcode -import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding +import org.matrix.android.sdk.api.util.toBase64NoPadding import java.security.SecureRandom -fun generateSharedSecretV2(): String { +internal fun generateSharedSecretV2(): String { val secureRandom = SecureRandom() // 8 bytes long diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/AsyncTransaction.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/AsyncTransaction.kt index 0df64568af..996515b359 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/AsyncTransaction.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/AsyncTransaction.kt @@ -35,7 +35,7 @@ internal fun <T> CoroutineScope.asyncTransaction(realmConfiguration: RealmConfig } } -suspend fun <T> awaitTransaction(config: RealmConfiguration, transaction: suspend (realm: Realm) -> T): T { +internal suspend fun <T> awaitTransaction(config: RealmConfiguration, transaction: suspend (realm: Realm) -> T): T { return withContext(Realm.WRITE_EXECUTOR.asCoroutineDispatcher()) { Realm.getInstance(config).use { bgRealm -> if (!bgRealm.isInTransaction) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt index 2319b7d8a0..6c793e822a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt @@ -119,7 +119,7 @@ internal fun ChunkEntity.addTimelineEvent(roomId: String, return timelineEventEntity } -fun computeIsUnique( +internal fun computeIsUnique( realm: Realm, roomId: String, isLastForward: Boolean, @@ -253,6 +253,9 @@ internal fun ChunkEntity.isMoreRecentThan(chunkToCheck: ChunkEntity, dimber: Dim if (this.doesNextChunksVerifyCondition { it == chunkToCheck }) { return false.also { dimber?.i { "isMoreReacentThan = false (this->ctc)" } } } + if (this.doesNextChunksVerifyCondition { it == chunkToCheck }) { + return false + } // Otherwise check if this chunk is linked to last forward if (this.doesNextChunksVerifyCondition { it.isLastForward }) { return true.also { dimber?.i { "isMoreReacentThan = true (this->isLastForward)" } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadSummaryHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadSummaryHelper.kt index 7087f07162..24de26eeea 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadSummaryHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ThreadSummaryHelper.kt @@ -22,13 +22,13 @@ import io.realm.Sort import io.realm.kotlin.createObject import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummary import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummaryUpdateType -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.database.mapper.toEntity import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/EventMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/EventMapper.kt index c3302f5ccb..3083df062e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/EventMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/EventMapper.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.database.mapper import com.squareup.moshi.JsonDataException import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.UnsignedData @@ -26,7 +27,6 @@ import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.room.sender.SenderInfo import org.matrix.android.sdk.api.session.threads.ThreadDetails import org.matrix.android.sdk.api.session.threads.ThreadNotificationState -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.database.model.EventEntity import org.matrix.android.sdk.internal.di.MoshiProvider import timber.log.Timber diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt index e259ed3373..134d4c2dc8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/mapper/RoomSummaryMapper.kt @@ -16,7 +16,8 @@ package org.matrix.android.sdk.internal.database.mapper -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.room.model.RoomEncryptionAlgorithm import org.matrix.android.sdk.api.session.room.model.RoomJoinRules import org.matrix.android.sdk.api.session.room.model.RoomSummary @@ -24,7 +25,6 @@ import org.matrix.android.sdk.api.session.room.model.SpaceChildInfo import org.matrix.android.sdk.api.session.room.model.SpaceParentInfo import org.matrix.android.sdk.api.session.room.model.tag.RoomTag import org.matrix.android.sdk.api.session.typing.TypingUsersTracker -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.model.presence.toUserPresence import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo001.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo001.kt index 831c6280ad..7bed23066c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo001.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo001.kt @@ -20,7 +20,7 @@ import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo001(realm: DynamicRealm) : RealmMigrator(realm, 1) { +internal class MigrateSessionTo001(realm: DynamicRealm) : RealmMigrator(realm, 1) { override fun doMigrate(realm: DynamicRealm) { // Add hasFailedSending in RoomSummary and a small warning icon on room list diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo002.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo002.kt index 215e558e2a..9fa36248f8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo002.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo002.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.database.migration import io.realm.DynamicRealm import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo002(realm: DynamicRealm) : RealmMigrator(realm, 2) { +internal class MigrateSessionTo002(realm: DynamicRealm) : RealmMigrator(realm, 2) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("HomeServerCapabilitiesEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo003.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo003.kt index bc0b79d7e6..b4aca53ece 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo003.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo003.kt @@ -20,7 +20,7 @@ import io.realm.DynamicRealm import org.matrix.android.sdk.internal.extensions.forceRefreshOfHomeServerCapabilities import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo003(realm: DynamicRealm) : RealmMigrator(realm, 3) { +internal class MigrateSessionTo003(realm: DynamicRealm) : RealmMigrator(realm, 3) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("HomeServerCapabilitiesEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo004.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo004.kt index be13ae2c2f..0d91aab7d8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo004.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo004.kt @@ -20,7 +20,7 @@ import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.PendingThreePidEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo004(realm: DynamicRealm) : RealmMigrator(realm, 4) { +internal class MigrateSessionTo004(realm: DynamicRealm) : RealmMigrator(realm, 4) { override fun doMigrate(realm: DynamicRealm) { realm.schema.create("PendingThreePidEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo005.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo005.kt index b4826b23a4..67e91d85cc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo005.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo005.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.database.migration import io.realm.DynamicRealm import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo005(realm: DynamicRealm) : RealmMigrator(realm, 5) { +internal class MigrateSessionTo005(realm: DynamicRealm) : RealmMigrator(realm, 5) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("HomeServerCapabilitiesEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo006.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo006.kt index 3d7f26ccee..8eccc229e7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo006.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo006.kt @@ -20,7 +20,7 @@ import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo006(realm: DynamicRealm) : RealmMigrator(realm, 6) { +internal class MigrateSessionTo006(realm: DynamicRealm) : RealmMigrator(realm, 6) { override fun doMigrate(realm: DynamicRealm) { realm.schema.create("PreviewUrlCacheEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo007.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo007.kt index be8c8ce9c6..5d1ff80367 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo007.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo007.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.database.model.RoomEntityFields import org.matrix.android.sdk.internal.database.model.RoomMembersLoadStatusType import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo007(realm: DynamicRealm) : RealmMigrator(realm, 7) { +internal class MigrateSessionTo007(realm: DynamicRealm) : RealmMigrator(realm, 7) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("RoomEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo008.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo008.kt index d46730ef70..b61bf7e6fa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo008.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo008.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.database.model.EditAggregatedSummaryEntit import org.matrix.android.sdk.internal.database.model.EditionOfEventFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo008(realm: DynamicRealm) : RealmMigrator(realm, 8) { +internal class MigrateSessionTo008(realm: DynamicRealm) : RealmMigrator(realm, 8) { override fun doMigrate(realm: DynamicRealm) { val editionOfEventSchema = realm.schema.create("EditionOfEvent") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo009.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo009.kt index 370430b9e3..149d322f66 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo009.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo009.kt @@ -25,7 +25,7 @@ import org.matrix.android.sdk.internal.database.model.RoomTagEntityFields import org.matrix.android.sdk.internal.database.model.TimelineEventEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo009(realm: DynamicRealm) : RealmMigrator(realm, 9) { +internal class MigrateSessionTo009(realm: DynamicRealm) : RealmMigrator(realm, 9) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("RoomSummaryEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo010.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo010.kt index b968862d10..aae80423ac 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo010.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo010.kt @@ -27,7 +27,7 @@ import org.matrix.android.sdk.internal.database.model.SpaceParentSummaryEntityFi import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo010(realm: DynamicRealm) : RealmMigrator(realm, 10) { +internal class MigrateSessionTo010(realm: DynamicRealm) : RealmMigrator(realm, 10) { override fun doMigrate(realm: DynamicRealm) { realm.schema.create("SpaceChildSummaryEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo011.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo011.kt index 92ee26df42..5ba201dd46 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo011.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo011.kt @@ -20,7 +20,7 @@ import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.EventEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo011(realm: DynamicRealm) : RealmMigrator(realm, 11) { +internal class MigrateSessionTo011(realm: DynamicRealm) : RealmMigrator(realm, 11) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("EventEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo012.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo012.kt index a914cadd80..f72cd3064f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo012.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo012.kt @@ -26,7 +26,7 @@ import org.matrix.android.sdk.internal.database.model.SpaceChildSummaryEntityFie import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo012(realm: DynamicRealm) : RealmMigrator(realm, 12) { +internal class MigrateSessionTo012(realm: DynamicRealm) : RealmMigrator(realm, 12) { override fun doMigrate(realm: DynamicRealm) { val joinRulesContentAdapter = MoshiProvider.providesMoshi().adapter(RoomJoinRulesContent::class.java) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo013.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo013.kt index 2ea0303802..2823a69ff1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo013.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo013.kt @@ -20,7 +20,7 @@ import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.SpaceChildSummaryEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo013(realm: DynamicRealm) : RealmMigrator(realm, 13) { +internal class MigrateSessionTo013(realm: DynamicRealm) : RealmMigrator(realm, 13) { override fun doMigrate(realm: DynamicRealm) { // Fix issue with the nightly build. Eventually play again the migration which has been included in migrateTo12() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo014.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo014.kt index c524b6f284..4a27c8bb12 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo014.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo014.kt @@ -24,7 +24,7 @@ import org.matrix.android.sdk.internal.database.model.RoomEntityFields import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo014(realm: DynamicRealm) : RealmMigrator(realm, 14) { +internal class MigrateSessionTo014(realm: DynamicRealm) : RealmMigrator(realm, 14) { override fun doMigrate(realm: DynamicRealm) { val roomAccountDataSchema = realm.schema.create("RoomAccountDataEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo015.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo015.kt index 329964a9a4..f45f9b39b1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo015.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo015.kt @@ -22,7 +22,7 @@ import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields import org.matrix.android.sdk.internal.query.process import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo015(realm: DynamicRealm) : RealmMigrator(realm, 15) { +internal class MigrateSessionTo015(realm: DynamicRealm) : RealmMigrator(realm, 15) { override fun doMigrate(realm: DynamicRealm) { // fix issue with flattenParentIds on DM that kept growing with duplicate diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo016.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo016.kt index b2fa54a05c..69f6c9f172 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo016.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo016.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEnti import org.matrix.android.sdk.internal.extensions.forceRefreshOfHomeServerCapabilities import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo016(realm: DynamicRealm) : RealmMigrator(realm, 16) { +internal class MigrateSessionTo016(realm: DynamicRealm) : RealmMigrator(realm, 16) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("HomeServerCapabilitiesEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo017.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo017.kt index 95d67b9ad8..4d8db92b69 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo017.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo017.kt @@ -20,7 +20,7 @@ import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.EventInsertEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo017(realm: DynamicRealm) : RealmMigrator(realm, 17) { +internal class MigrateSessionTo017(realm: DynamicRealm) : RealmMigrator(realm, 17) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("EventInsertEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo018.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo018.kt index b415c51d4b..559b8979e1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo018.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo018.kt @@ -22,7 +22,7 @@ import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields import org.matrix.android.sdk.internal.database.model.presence.UserPresenceEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo018(realm: DynamicRealm) : RealmMigrator(realm, 18) { +internal class MigrateSessionTo018(realm: DynamicRealm) : RealmMigrator(realm, 18) { override fun doMigrate(realm: DynamicRealm) { realm.schema.create("UserPresenceEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo019.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo019.kt index d0b368be46..d63ef62889 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo019.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo019.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields import org.matrix.android.sdk.internal.util.Normalizer import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo019(realm: DynamicRealm, +internal class MigrateSessionTo019(realm: DynamicRealm, private val normalizer: Normalizer) : RealmMigrator(realm, 19) { override fun doMigrate(realm: DynamicRealm) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo020.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo020.kt index c7f6e3ceed..e0075894ed 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo020.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo020.kt @@ -20,7 +20,7 @@ import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.ChunkEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo020(realm: DynamicRealm) : RealmMigrator(realm, 20) { +internal class MigrateSessionTo020(realm: DynamicRealm) : RealmMigrator(realm, 20) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("ChunkEntity")?.apply { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo021.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo021.kt index 6b6952e697..2f880a29dc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo021.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo021.kt @@ -18,14 +18,14 @@ package org.matrix.android.sdk.internal.database.migration import io.realm.DynamicRealm import org.matrix.android.sdk.api.session.events.model.EventType -import org.matrix.android.sdk.internal.crypto.model.event.EncryptionEventContent +import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields import org.matrix.android.sdk.internal.database.model.EventEntityFields import org.matrix.android.sdk.internal.database.model.RoomSummaryEntityFields import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo021(realm: DynamicRealm) : RealmMigrator(realm, 21) { +internal class MigrateSessionTo021(realm: DynamicRealm) : RealmMigrator(realm, 21) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("RoomSummaryEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo022.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo022.kt index e78a9d05da..f55700d36d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo022.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo022.kt @@ -23,7 +23,7 @@ import org.matrix.android.sdk.internal.database.model.RoomEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber -class MigrateSessionTo022(realm: DynamicRealm) : RealmMigrator(realm, 22) { +internal class MigrateSessionTo022(realm: DynamicRealm) : RealmMigrator(realm, 22) { override fun doMigrate(realm: DynamicRealm) { val listJoinedRoomIds = realm.where("RoomEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo023.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo023.kt index 0bb8ceeaa5..a3ce0b5414 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo023.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo023.kt @@ -22,7 +22,7 @@ import org.matrix.android.sdk.api.session.threads.ThreadNotificationState import org.matrix.android.sdk.internal.database.model.EventEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo023(realm: DynamicRealm) : RealmMigrator(realm, 23) { +internal class MigrateSessionTo023(realm: DynamicRealm) : RealmMigrator(realm, 23) { override fun doMigrate(realm: DynamicRealm) { val eventEntity = realm.schema.get("TimelineEventEntity") ?: return diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo024.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo024.kt index ff88972566..fc17bf9b28 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo024.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo024.kt @@ -20,7 +20,7 @@ import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo024(realm: DynamicRealm) : RealmMigrator(realm, 24) { +internal class MigrateSessionTo024(realm: DynamicRealm) : RealmMigrator(realm, 24) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("PreviewUrlCacheEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo025.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo025.kt index 237b016ac2..a57fd52ec1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo025.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo025.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.database.model.HomeServerCapabilitiesEnti import org.matrix.android.sdk.internal.extensions.forceRefreshOfHomeServerCapabilities import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateSessionTo025(realm: DynamicRealm) : RealmMigrator(realm, 25) { +internal class MigrateSessionTo025(realm: DynamicRealm) : RealmMigrator(realm, 25) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("HomeServerCapabilitiesEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo026.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo026.kt index f108a91ecf..35a6135ba2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo026.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/migration/MigrateSessionTo026.kt @@ -31,7 +31,7 @@ import org.matrix.android.sdk.internal.util.database.RealmMigrator * Live thread list: using enhanced /messages api MSC3440 * Live thread timeline: using /relations api */ -class MigrateSessionTo026(realm: DynamicRealm) : RealmMigrator(realm, 26) { +internal class MigrateSessionTo026(realm: DynamicRealm) : RealmMigrator(realm, 26) { override fun doMigrate(realm: DynamicRealm) { realm.schema.get("ChunkEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventEntity.kt index 09be98aa96..ba80cc8302 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/EventEntity.kt @@ -18,10 +18,10 @@ package org.matrix.android.sdk.internal.database.model import io.realm.RealmObject import io.realm.annotations.Index +import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.threads.ThreadNotificationState -import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.extensions.assertIsManaged diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt index 3a67da5cad..3e87f53f0f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/model/RoomSummaryEntity.kt @@ -21,8 +21,8 @@ import io.realm.RealmList import io.realm.RealmObject import io.realm.annotations.Index import io.realm.annotations.PrimaryKey -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomJoinRules import org.matrix.android.sdk.api.session.room.model.RoomSummary diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt index d9a4f1bde1..2fad2d8e78 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MatrixComponent.kt @@ -28,12 +28,14 @@ import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.auth.AuthenticationService import org.matrix.android.sdk.api.auth.HomeServerHistoryService import org.matrix.android.sdk.api.raw.RawService +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.auth.AuthModule import org.matrix.android.sdk.internal.auth.SessionParamsStore import org.matrix.android.sdk.internal.raw.RawModule import org.matrix.android.sdk.internal.session.MockHttpInterceptor import org.matrix.android.sdk.internal.session.TestInterceptor +import org.matrix.android.sdk.internal.settings.SettingsModule import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver import org.matrix.android.sdk.internal.util.system.SystemModule @@ -46,6 +48,7 @@ import java.io.File NetworkModule::class, AuthModule::class, RawModule::class, + SettingsModule::class, SystemModule::class, NoOpTestModule::class ]) @@ -66,6 +69,8 @@ internal interface MatrixComponent { fun rawService(): RawService + fun lightweightSettingsStorage(): LightweightSettingsStorage + fun homeServerHistoryService(): HomeServerHistoryService fun context(): Context diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MoshiProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MoshiProvider.kt index 9e50e9efe8..10b0d4fb13 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MoshiProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/MoshiProvider.kt @@ -37,7 +37,7 @@ import org.matrix.android.sdk.internal.network.parsing.TlsVersionMoshiAdapter import org.matrix.android.sdk.internal.network.parsing.UriMoshiAdapter import org.matrix.android.sdk.internal.session.sync.parsing.DefaultLazyRoomSyncEphemeralJsonAdapter -object MoshiProvider { +internal object MoshiProvider { private val moshi: Moshi = Moshi.Builder() .add(UriMoshiAdapter()) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/SerializeNulls.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/SerializeNulls.kt index 0d8fdde813..9bd197e42e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/SerializeNulls.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/SerializeNulls.kt @@ -25,7 +25,7 @@ import java.lang.reflect.Type @Retention(AnnotationRetention.RUNTIME) @JsonQualifier -annotation class SerializeNulls { +internal annotation class SerializeNulls { companion object { val JSON_ADAPTER_FACTORY: JsonAdapter.Factory = object : JsonAdapter.Factory { @Nullable diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/LiveData.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/LiveData.kt index fecbb874d0..8f57960b95 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/LiveData.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/LiveData.kt @@ -18,35 +18,7 @@ package org.matrix.android.sdk.internal.extensions import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.LiveData -import androidx.lifecycle.MediatorLiveData -import androidx.lifecycle.Observer -inline fun <T> LiveData<T>.observeK(owner: LifecycleOwner, crossinline observer: (T?) -> Unit) { - this.observe(owner, Observer { observer(it) }) -} - -inline fun <T> LiveData<T>.observeNotNull(owner: LifecycleOwner, crossinline observer: (T) -> Unit) { - this.observe(owner, Observer { it?.run(observer) }) -} - -fun <T1, T2, R> combineLatest(source1: LiveData<T1>, source2: LiveData<T2>, mapper: (T1, T2) -> R): LiveData<R> { - val combined = MediatorLiveData<R>() - var source1Result: T1? = null - var source2Result: T2? = null - - fun notify() { - if (source1Result != null && source2Result != null) { - combined.value = mapper(source1Result!!, source2Result!!) - } - } - - combined.addSource(source1) { - source1Result = it - notify() - } - combined.addSource(source2) { - source2Result = it - notify() - } - return combined +internal inline fun <T> LiveData<T>.observeNotNull(owner: LifecycleOwner, crossinline observer: (T) -> Unit) { + this.observe(owner) { it?.run(observer) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Primitives.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Primitives.kt index 855e7edac3..290f06142c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Primitives.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Primitives.kt @@ -19,4 +19,4 @@ package org.matrix.android.sdk.internal.extensions /** * Convert a signed byte to a int value */ -fun Byte.toUnsignedInt() = toInt() and 0xff +internal fun Byte.toUnsignedInt() = toInt() and 0xff diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Result.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Result.kt index 12adf16cbc..b85102ef17 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Result.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/extensions/Result.kt @@ -17,15 +17,7 @@ package org.matrix.android.sdk.internal.extensions import org.matrix.android.sdk.api.MatrixCallback -fun <A> Result<A>.foldToCallback(callback: MatrixCallback<A>): Unit = fold( +internal fun <A> Result<A>.foldToCallback(callback: MatrixCallback<A>): Unit = fold( { callback.onSuccess(it) }, { callback.onFailure(it) } ) - -@Suppress("UNCHECKED_CAST") // We're casting null failure results to R -inline fun <T, R> Result<T>.andThen(block: (T) -> Result<R>): Result<R> { - return when (val result = getOrNull()) { - null -> this as Result<R> - else -> block(result) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt index 22085e30fc..0a76fb2eef 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/DefaultLegacySessionImporter.kt @@ -26,13 +26,13 @@ import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.api.auth.data.SessionParams import org.matrix.android.sdk.api.auth.data.WellKnownBaseConfig import org.matrix.android.sdk.api.legacy.LegacySessionImporter +import org.matrix.android.sdk.api.network.ssl.Fingerprint +import org.matrix.android.sdk.api.util.md5 import org.matrix.android.sdk.internal.auth.SessionParamsStore import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreMigration import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule import org.matrix.android.sdk.internal.database.RealmKeysUtils import org.matrix.android.sdk.internal.legacy.riot.LoginStorage -import org.matrix.android.sdk.internal.network.ssl.Fingerprint -import org.matrix.android.sdk.internal.util.md5 import timber.log.Timber import java.io.File import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Credentials.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Credentials.java index 0ca0c7db85..bbed159e3c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Credentials.java +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Credentials.java @@ -21,11 +21,9 @@ import org.jetbrains.annotations.Nullable; import org.json.JSONException; import org.json.JSONObject; -/* - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - */ - /** + * <b>IMPORTANT:</b> This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose + * * The user's credentials. */ public class Credentials { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Fingerprint.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Fingerprint.java index 74a3f1ac55..82541d38f6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Fingerprint.java +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/Fingerprint.java @@ -23,11 +23,9 @@ import org.json.JSONObject; import java.util.Arrays; -/* - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - */ - /** + * <b>IMPORTANT:</b> This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose + * * Represents a X509 Certificate fingerprint. */ public class Fingerprint { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java index 75fc187c45..a1b46f6c09 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/HomeServerConnectionConfig.java @@ -35,11 +35,9 @@ import okhttp3.CipherSuite; import okhttp3.TlsVersion; import timber.log.Timber; -/* - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - */ - /** + * <b>IMPORTANT:</b> This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose + * * Represents how to connect to a specific Homeserver, may include credentials to use. */ public class HomeServerConnectionConfig { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/LoginStorage.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/LoginStorage.java index 62f90f563e..924bd461ed 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/LoginStorage.java +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/LoginStorage.java @@ -29,11 +29,9 @@ import java.util.List; import timber.log.Timber; -/* - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - */ - /** + * <b>IMPORTANT:</b> This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose + * * Stores login credentials in SharedPreferences. */ public class LoginStorage { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnown.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnown.kt index 17fd0925f8..3b4bd1b1a3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnown.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnown.kt @@ -18,11 +18,9 @@ package org.matrix.android.sdk.internal.legacy.riot import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -/* - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - */ - /** + * <b>IMPORTANT:</b> This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose + * * https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery * <pre> * { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownBaseConfig.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownBaseConfig.kt index 7bbdda5eaa..2a4ae295fd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownBaseConfig.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownBaseConfig.kt @@ -18,11 +18,9 @@ package org.matrix.android.sdk.internal.legacy.riot import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -/* - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - */ - /** + * <b>IMPORTANT:</b> This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose + * * https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery * <pre> * { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownManagerConfig.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownManagerConfig.kt index 4efb52d61c..6b1c67f7cb 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownManagerConfig.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownManagerConfig.kt @@ -15,10 +15,9 @@ */ package org.matrix.android.sdk.internal.legacy.riot -/* - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose +/** + * <b>IMPORTANT:</b> This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose */ - data class WellKnownManagerConfig( val apiUrl: String, val uiUrl: String diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownPreferredConfig.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownPreferredConfig.kt index feefdf920d..beb95a1d6f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownPreferredConfig.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/legacy/riot/WellKnownPreferredConfig.kt @@ -18,11 +18,9 @@ package org.matrix.android.sdk.internal.legacy.riot import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -/* - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - */ - /** + * <b>IMPORTANT:</b> This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose + * * https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery * <pre> * { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/HttpHeaders.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/HttpHeaders.kt index 26bdd90507..402e956caa 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/HttpHeaders.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/HttpHeaders.kt @@ -16,7 +16,7 @@ package org.matrix.android.sdk.internal.network -object HttpHeaders { +internal object HttpHeaders { const val Authorization = "Authorization" const val UserAgent = "User-Agent" diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConnectivityChecker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConnectivityChecker.kt index e32f6be6fc..cd7c99b8f9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConnectivityChecker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/NetworkConnectivityChecker.kt @@ -25,7 +25,7 @@ import java.util.Collections import java.util.concurrent.atomic.AtomicBoolean import javax.inject.Inject -interface NetworkConnectivityChecker { +internal interface NetworkConnectivityChecker { /** * Returns true when internet is available */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UnitConverterFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UnitConverterFactory.kt index 513d8c5c86..f2571ab73f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UnitConverterFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/UnitConverterFactory.kt @@ -21,7 +21,7 @@ import retrofit2.Converter import retrofit2.Retrofit import java.lang.reflect.Type -object UnitConverterFactory : Converter.Factory() { +internal object UnitConverterFactory : Converter.Factory() { override fun responseBodyConverter(type: Type, annotations: Array<out Annotation>, retrofit: Retrofit): Converter<ResponseBody, *>? { return if (type == Unit::class.java) UnitConverter else null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt index 27684bbf1a..6efa347d3a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/CheckNumberType.kt @@ -28,7 +28,7 @@ import java.math.BigDecimal /** * This is used to check if NUMBER in json is integer or double, so we can preserve typing when serializing/deserializing in a row. */ -interface CheckNumberType { +internal interface CheckNumberType { companion object { val JSON_ADAPTER_FACTORY = object : JsonAdapter.Factory { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/ForceToBoolean.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/ForceToBoolean.kt index f3b4cff34c..628486bb5f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/ForceToBoolean.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/ForceToBoolean.kt @@ -25,7 +25,7 @@ import timber.log.Timber @JsonQualifier @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.FIELD, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.FUNCTION) -annotation class ForceToBoolean +internal annotation class ForceToBoolean internal class ForceToBooleanJsonAdapter { @ToJson diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.java b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.java deleted file mode 100644 index c9bf6cc662..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.network.parsing; - -import com.squareup.moshi.JsonAdapter; -import com.squareup.moshi.JsonDataException; -import com.squareup.moshi.JsonReader; -import com.squareup.moshi.JsonWriter; -import com.squareup.moshi.Moshi; -import com.squareup.moshi.Types; - -import java.io.IOException; -import java.lang.annotation.Annotation; -import java.lang.reflect.Type; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -import javax.annotation.CheckReturnValue; - -/** - * A JsonAdapter factory for polymorphic types. This is useful when the type is not known before - * decoding the JSON. This factory's adapters expect JSON in the format of a JSON object with a - * key whose value is a label that determines the type to which to map the JSON object. - */ -public final class RuntimeJsonAdapterFactory<T> implements JsonAdapter.Factory { - final Class<T> baseType; - final String labelKey; - final Class fallbackType; - final Map<String, Type> labelToType = new LinkedHashMap<>(); - - /** - * @param baseType The base type for which this factory will create adapters. Cannot be Object. - * @param labelKey The key in the JSON object whose value determines the type to which to map the - * JSON object. - */ - @CheckReturnValue - public static <T> RuntimeJsonAdapterFactory<T> of(Class<T> baseType, String labelKey, Class<? extends T> fallbackType) { - if (baseType == null) throw new NullPointerException("baseType == null"); - if (labelKey == null) throw new NullPointerException("labelKey == null"); - if (baseType == Object.class) { - throw new IllegalArgumentException( - "The base type must not be Object. Consider using a marker interface."); - } - return new RuntimeJsonAdapterFactory<>(baseType, labelKey, fallbackType); - } - - RuntimeJsonAdapterFactory(Class<T> baseType, String labelKey, Class fallbackType) { - this.baseType = baseType; - this.labelKey = labelKey; - this.fallbackType = fallbackType; - } - - /** - * Register the subtype that can be created based on the label. When an unknown type is found - * during encoding an {@linkplain IllegalArgumentException} will be thrown. When an unknown label - * is found during decoding a {@linkplain JsonDataException} will be thrown. - */ - public RuntimeJsonAdapterFactory<T> registerSubtype(Class<? extends T> subtype, String label) { - if (subtype == null) throw new NullPointerException("subtype == null"); - if (label == null) throw new NullPointerException("label == null"); - if (labelToType.containsKey(label) || labelToType.containsValue(subtype)) { - throw new IllegalArgumentException("Subtypes and labels must be unique."); - } - labelToType.put(label, subtype); - return this; - } - - @Override - public JsonAdapter<?> create(Type type, Set<? extends Annotation> annotations, Moshi moshi) { - if (Types.getRawType(type) != baseType || !annotations.isEmpty()) { - return null; - } - int size = labelToType.size(); - Map<String, JsonAdapter<Object>> labelToAdapter = new LinkedHashMap<>(size); - Map<Type, String> typeToLabel = new LinkedHashMap<>(size); - for (Map.Entry<String, Type> entry : labelToType.entrySet()) { - String label = entry.getKey(); - Type typeValue = entry.getValue(); - typeToLabel.put(typeValue, label); - labelToAdapter.put(label, moshi.adapter(typeValue)); - } - - final JsonAdapter<Object> fallbackAdapter = moshi.adapter(fallbackType); - JsonAdapter<Object> objectJsonAdapter = moshi.adapter(Object.class); - - return new RuntimeJsonAdapter(labelKey, labelToAdapter, typeToLabel, - objectJsonAdapter, fallbackAdapter).nullSafe(); - } - - static final class RuntimeJsonAdapter extends JsonAdapter<Object> { - final String labelKey; - final Map<String, JsonAdapter<Object>> labelToAdapter; - final Map<Type, String> typeToLabel; - final JsonAdapter<Object> objectJsonAdapter; - final JsonAdapter<Object> fallbackAdapter; - - RuntimeJsonAdapter(String labelKey, Map<String, JsonAdapter<Object>> labelToAdapter, - Map<Type, String> typeToLabel, JsonAdapter<Object> objectJsonAdapter, - JsonAdapter<Object> fallbackAdapter) { - this.labelKey = labelKey; - this.labelToAdapter = labelToAdapter; - this.typeToLabel = typeToLabel; - this.objectJsonAdapter = objectJsonAdapter; - this.fallbackAdapter = fallbackAdapter; - } - - @Override - public Object fromJson(JsonReader reader) throws IOException { - JsonReader.Token peekedToken = reader.peek(); - if (peekedToken != JsonReader.Token.BEGIN_OBJECT) { - throw new JsonDataException("Expected BEGIN_OBJECT but was " + peekedToken - + " at path " + reader.getPath()); - } - Object jsonValue = reader.readJsonValue(); - Map<String, Object> jsonObject = (Map<String, Object>) jsonValue; - Object label = jsonObject.get(labelKey); - if (!(label instanceof String)) { - return null; - } - JsonAdapter<Object> adapter = labelToAdapter.get(label); - if (adapter == null) { - return fallbackAdapter.fromJsonValue(jsonValue); - } - return adapter.fromJsonValue(jsonValue); - } - - @Override - public void toJson(JsonWriter writer, Object value) throws IOException { - Class<?> type = value.getClass(); - String label = typeToLabel.get(type); - if (label == null) { - throw new IllegalArgumentException("Expected one of " - + typeToLabel.keySet() - + " but found " - + value - + ", a " - + value.getClass() - + ". Register this subtype."); - } - JsonAdapter<Object> adapter = labelToAdapter.get(label); - Map<String, Object> jsonValue = (Map<String, Object>) adapter.toJsonValue(value); - - Map<String, Object> valueWithLabel = new LinkedHashMap<>(1 + jsonValue.size()); - valueWithLabel.put(labelKey, label); - valueWithLabel.putAll(jsonValue); - objectJsonAdapter.toJson(writer, valueWithLabel); - } - - @Override - public String toString() { - return "RuntimeJsonAdapter(" + labelKey + ")"; - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.kt new file mode 100644 index 0000000000..0aaa4991cd --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/parsing/RuntimeJsonAdapterFactory.kt @@ -0,0 +1,126 @@ +/* + * Copyright 2020 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.matrix.android.sdk.internal.network.parsing + +import com.squareup.moshi.JsonAdapter +import com.squareup.moshi.JsonDataException +import com.squareup.moshi.JsonReader +import com.squareup.moshi.JsonWriter +import com.squareup.moshi.Moshi +import com.squareup.moshi.Types +import java.io.IOException +import java.lang.reflect.Type +import javax.annotation.CheckReturnValue + +/** + * A JsonAdapter factory for polymorphic types. This is useful when the type is not known before + * decoding the JSON. This factory's adapters expect JSON in the format of a JSON object with a + * key whose value is a label that determines the type to which to map the JSON object. + */ +internal class RuntimeJsonAdapterFactory<T>( + private val baseType: Class<T>, + private val labelKey: String, + private val fallbackType: Class<*> +) : JsonAdapter.Factory { + private val labelToType: MutableMap<String, Type> = LinkedHashMap() + + /** + * Register the subtype that can be created based on the label. When an unknown type is found + * during encoding an [IllegalArgumentException] will be thrown. When an unknown label + * is found during decoding a [JsonDataException] will be thrown. + */ + fun registerSubtype(subtype: Class<out T>?, label: String?): RuntimeJsonAdapterFactory<T> { + if (subtype == null) throw NullPointerException("subtype == null") + if (label == null) throw NullPointerException("label == null") + require(!(labelToType.containsKey(label) || labelToType.containsValue(subtype))) { "Subtypes and labels must be unique." } + labelToType[label] = subtype + return this + } + + override fun create(type: Type, annotations: Set<Annotation?>, moshi: Moshi): JsonAdapter<*>? { + if (Types.getRawType(type) != baseType || !annotations.isEmpty()) { + return null + } + val size = labelToType.size + val labelToAdapter: MutableMap<String, JsonAdapter<Any>> = LinkedHashMap(size) + val typeToLabel: MutableMap<Type, String> = LinkedHashMap(size) + for ((label, typeValue) in labelToType) { + typeToLabel[typeValue] = label + labelToAdapter[label] = moshi.adapter(typeValue) + } + val fallbackAdapter = moshi.adapter<Any>(fallbackType) + val objectJsonAdapter = moshi.adapter(Any::class.java) + return RuntimeJsonAdapter(labelKey, labelToAdapter, typeToLabel, + objectJsonAdapter, fallbackAdapter).nullSafe() + } + + @Suppress("UNCHECKED_CAST") + internal class RuntimeJsonAdapter(val labelKey: String, + val labelToAdapter: Map<String, JsonAdapter<Any>>, + val typeToLabel: Map<Type, String>, + val objectJsonAdapter: JsonAdapter<Any>, + val fallbackAdapter: JsonAdapter<Any>) : JsonAdapter<Any?>() { + @Throws(IOException::class) + override fun fromJson(reader: JsonReader): Any? { + val peekedToken = reader.peek() + if (peekedToken != JsonReader.Token.BEGIN_OBJECT) { + throw JsonDataException("Expected BEGIN_OBJECT but was " + peekedToken + + " at path " + reader.path) + } + val jsonValue = reader.readJsonValue() + val jsonObject = jsonValue as Map<String, Any>? + val label = jsonObject!![labelKey] as? String ?: return null + val adapter = labelToAdapter[label] ?: return fallbackAdapter.fromJsonValue(jsonValue) + return adapter.fromJsonValue(jsonValue) + } + + @Throws(IOException::class) + override fun toJson(writer: JsonWriter, value: Any?) { + val type: Class<*> = value!!.javaClass + val label = typeToLabel[type] + ?: throw IllegalArgumentException("Expected one of " + + typeToLabel.keys + + " but found " + + value + + ", a " + + value.javaClass + + ". Register this subtype.") + val adapter = labelToAdapter[label]!! + val jsonValue = adapter.toJsonValue(value) as Map<String, Any>? + val valueWithLabel: MutableMap<String, Any> = LinkedHashMap(1 + jsonValue!!.size) + valueWithLabel[labelKey] = label + valueWithLabel.putAll(jsonValue) + objectJsonAdapter.toJson(writer, valueWithLabel) + } + + override fun toString(): String { + return "RuntimeJsonAdapter($labelKey)" + } + } + + companion object { + /** + * @param baseType The base type for which this factory will create adapters. Cannot be Object. + * @param labelKey The key in the JSON object whose value determines the type to which to map the + * JSON object. + */ + @CheckReturnValue + fun <T> of(baseType: Class<T>, labelKey: String, fallbackType: Class<out T>): RuntimeJsonAdapterFactory<T> { + require(baseType != Any::class.java) { "The base type must not be Object. Consider using a marker interface." } + return RuntimeJsonAdapterFactory(baseType, labelKey, fallbackType) + } + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt index 6f245aa6d8..ccae5ad14f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManager.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.network.ssl +import org.matrix.android.sdk.api.network.ssl.Fingerprint import java.security.cert.CertificateException import java.security.cert.X509Certificate import javax.net.ssl.X509TrustManager diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerApi24.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerApi24.kt index 4e58a0f2e5..574f1ef81d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerApi24.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerApi24.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.network.ssl import android.os.Build import androidx.annotation.RequiresApi +import org.matrix.android.sdk.api.network.ssl.Fingerprint import java.net.Socket import java.security.cert.CertificateException import java.security.cert.X509Certificate diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerProvider.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerProvider.kt index 57b97c75c5..f01ee7af24 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerProvider.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/PinnedTrustManagerProvider.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.network.ssl import android.os.Build +import org.matrix.android.sdk.api.network.ssl.Fingerprint import javax.net.ssl.X509ExtendedTrustManager import javax.net.ssl.X509TrustManager diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/UnrecognizedCertificateException.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/UnrecognizedCertificateException.kt index ca841f0ffb..62eb6cf1f6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/UnrecognizedCertificateException.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/UnrecognizedCertificateException.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.network.ssl +import org.matrix.android.sdk.api.network.ssl.Fingerprint import java.security.cert.CertificateException import java.security.cert.X509Certificate diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/query/QueryEnumListProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/query/QueryEnumListProcessor.kt index 5653d7171d..b4415afcbc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/query/QueryEnumListProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/query/QueryEnumListProcessor.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.query import io.realm.RealmObject import io.realm.RealmQuery -fun <T : RealmObject, E : Enum<E>> RealmQuery<T>.process(field: String, enums: List<Enum<E>>): RealmQuery<T> { +internal fun <T : RealmObject, E : Enum<E>> RealmQuery<T>.process(field: String, enums: List<Enum<E>>): RealmQuery<T> { val lastEnumValue = enums.lastOrNull() beginGroup() for (enumValue in enums) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/query/QueryStringValueProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/query/QueryStringValueProcessor.kt index b42bf2b8c7..ba4d05e747 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/query/QueryStringValueProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/query/QueryStringValueProcessor.kt @@ -24,7 +24,7 @@ import org.matrix.android.sdk.api.query.QueryStringValue.ContentQueryStringValue import org.matrix.android.sdk.internal.util.Normalizer import javax.inject.Inject -class QueryStringValueProcessor @Inject constructor( +internal class QueryStringValueProcessor @Inject constructor( private val normalizer: Normalizer ) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/migration/MigrateGlobalTo001.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/migration/MigrateGlobalTo001.kt index cff2f7b8e8..7b33257368 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/migration/MigrateGlobalTo001.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/raw/migration/MigrateGlobalTo001.kt @@ -20,7 +20,7 @@ import io.realm.DynamicRealm import org.matrix.android.sdk.internal.database.model.KnownServerUrlEntityFields import org.matrix.android.sdk.internal.util.database.RealmMigrator -class MigrateGlobalTo001(realm: DynamicRealm) : RealmMigrator(realm, 1) { +internal class MigrateGlobalTo001(realm: DynamicRealm) : RealmMigrator(realm, 1) { override fun doMigrate(realm: DynamicRealm) { realm.schema.create("KnownServerUrlEntity") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultFileService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultFileService.kt index 08651764c2..ac097f57ee 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultFileService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultFileService.kt @@ -30,14 +30,14 @@ import okhttp3.RequestBody.Companion.toRequestBody import org.matrix.android.sdk.api.MatrixCoroutineDispatchers import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.content.ContentUrlResolver +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt import org.matrix.android.sdk.api.session.file.FileService -import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt +import org.matrix.android.sdk.api.util.md5 import org.matrix.android.sdk.internal.crypto.attachments.MXEncryptedAttachments import org.matrix.android.sdk.internal.di.SessionDownloadsDirectory import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificateWithProgress import org.matrix.android.sdk.internal.session.download.DownloadProgressInterceptor.Companion.DOWNLOAD_PROGRESS_INTERCEPTOR_HEADER import org.matrix.android.sdk.internal.util.file.AtomicFileCreator -import org.matrix.android.sdk.internal.util.md5 import org.matrix.android.sdk.internal.util.writeToFile import timber.log.Timber import java.io.File diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultToDeviceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultToDeviceService.kt index 1615b8eef9..609acdd89c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultToDeviceService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/DefaultToDeviceService.kt @@ -17,10 +17,10 @@ package org.matrix.android.sdk.internal.session import org.matrix.android.sdk.api.session.ToDeviceService +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt index 531dea1d5a..0aae9f3105 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/SessionModule.kt @@ -45,6 +45,7 @@ import org.matrix.android.sdk.api.session.permalinks.PermalinkService import org.matrix.android.sdk.api.session.securestorage.SecureStorageService import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService import org.matrix.android.sdk.api.session.typing.TypingUsersTracker +import org.matrix.android.sdk.api.util.md5 import org.matrix.android.sdk.internal.crypto.secrets.DefaultSharedSecretStorageService import org.matrix.android.sdk.internal.crypto.tasks.DefaultRedactEventTask import org.matrix.android.sdk.internal.crypto.tasks.RedactEventTask @@ -87,6 +88,8 @@ import org.matrix.android.sdk.internal.session.integrationmanager.IntegrationMan import org.matrix.android.sdk.internal.session.openid.DefaultOpenIdService import org.matrix.android.sdk.internal.session.permalinks.DefaultPermalinkService import org.matrix.android.sdk.internal.session.room.EventRelationsAggregationProcessor +import org.matrix.android.sdk.internal.session.room.aggregation.livelocation.DefaultLiveLocationAggregationProcessor +import org.matrix.android.sdk.internal.session.room.aggregation.livelocation.LiveLocationAggregationProcessor import org.matrix.android.sdk.internal.session.room.create.RoomCreateEventProcessor import org.matrix.android.sdk.internal.session.room.prune.RedactionEventProcessor import org.matrix.android.sdk.internal.session.room.send.queue.EventSenderProcessor @@ -96,7 +99,6 @@ import org.matrix.android.sdk.internal.session.securestorage.DefaultSecureStorag import org.matrix.android.sdk.internal.session.typing.DefaultTypingUsersTracker import org.matrix.android.sdk.internal.session.user.accountdata.DefaultSessionAccountDataService import org.matrix.android.sdk.internal.session.widgets.DefaultWidgetURLFormatter -import org.matrix.android.sdk.internal.util.md5 import retrofit2.Retrofit import java.io.File import javax.inject.Provider @@ -104,7 +106,7 @@ import javax.inject.Qualifier @Qualifier @Retention(AnnotationRetention.RUNTIME) -annotation class MockHttpInterceptor +internal annotation class MockHttpInterceptor @Module internal abstract class SessionModule { @@ -390,4 +392,7 @@ internal abstract class SessionModule { @Binds abstract fun bindEventSenderProcessor(processor: EventSenderProcessorCoroutine): EventSenderProcessor + + @Binds + abstract fun bindLiveLocationAggregationProcessor(processor: DefaultLiveLocationAggregationProcessor): LiveLocationAggregationProcessor } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/StreamEventsManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/StreamEventsManager.kt index bb0ca11445..cfc26045a0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/StreamEventsManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/StreamEventsManager.kt @@ -22,8 +22,8 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.LiveEventListener +import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event -import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult import timber.log.Timber import javax.inject.Inject @@ -71,7 +71,7 @@ internal class StreamEventsManager @Inject constructor() { coroutineScope.launch { listeners.forEach { tryOrNull { - it.onEventDecrypted(event.eventId ?: "", event.roomId ?: "", result.clearEvent) + it.onEventDecrypted(event, result.clearEvent) } } } @@ -82,7 +82,7 @@ internal class StreamEventsManager @Inject constructor() { coroutineScope.launch { listeners.forEach { tryOrNull { - it.onEventDecryptionError(event.eventId ?: "", event.roomId ?: "", error) + it.onEventDecryptionError(event, error) } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/TestInterceptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/TestInterceptor.kt index fad68afd8a..5b2ba91ba2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/TestInterceptor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/TestInterceptor.kt @@ -18,6 +18,6 @@ package org.matrix.android.sdk.internal.session import okhttp3.Interceptor -interface TestInterceptor : Interceptor { +internal interface TestInterceptor : Interceptor { var sessionId: String? } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/DefaultContentUrlResolver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/DefaultContentUrlResolver.kt index 660ab8726f..5d77424482 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/DefaultContentUrlResolver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/DefaultContentUrlResolver.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.api.MatrixUrls.removeMxcPrefix import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.api.session.content.ContentUrlResolver import org.matrix.android.sdk.api.session.contentscanner.ContentScannerService -import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt import org.matrix.android.sdk.internal.network.NetworkConstants import org.matrix.android.sdk.internal.session.contentscanner.ScanEncryptorUtils import org.matrix.android.sdk.internal.session.contentscanner.model.toJson diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt index 77dcbed18e..12d3fd4be8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/content/UploadContentWorker.kt @@ -25,6 +25,7 @@ import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.content.ContentAttachmentData +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent @@ -35,7 +36,6 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageVideoContent import org.matrix.android.sdk.api.util.MimeTypes import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.crypto.attachments.MXEncryptedAttachments -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.network.ProgressRequestBody diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/DefaultContentScannerService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/DefaultContentScannerService.kt index 4ecb337603..da7e2d102e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/DefaultContentScannerService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/DefaultContentScannerService.kt @@ -23,8 +23,8 @@ import okhttp3.OkHttpClient import org.matrix.android.sdk.api.session.contentscanner.ContentScannerService import org.matrix.android.sdk.api.session.contentscanner.ScanState import org.matrix.android.sdk.api.session.contentscanner.ScanStatusInfo +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt import org.matrix.android.sdk.api.util.Optional -import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt import org.matrix.android.sdk.internal.di.Unauthenticated import org.matrix.android.sdk.internal.network.RetrofitFactory import org.matrix.android.sdk.internal.session.SessionScope diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/DisabledContentScannerService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/DisabledContentScannerService.kt index 9087c71566..41c444ad83 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/DisabledContentScannerService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/DisabledContentScannerService.kt @@ -20,8 +20,8 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.MutableLiveData import org.matrix.android.sdk.api.session.contentscanner.ContentScannerService import org.matrix.android.sdk.api.session.contentscanner.ScanStatusInfo +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt import org.matrix.android.sdk.api.util.Optional -import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt import org.matrix.android.sdk.internal.session.SessionScope import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/ScanEncryptorUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/ScanEncryptorUtils.kt index 8fc84a487e..7d14e4ed80 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/ScanEncryptorUtils.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/ScanEncryptorUtils.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.session.contentscanner -import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileKey +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileKey import org.matrix.android.sdk.internal.crypto.tools.withOlmEncryption import org.matrix.android.sdk.internal.session.contentscanner.model.DownloadBody import org.matrix.android.sdk.internal.session.contentscanner.model.EncryptedBody diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/model/DownloadBody.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/model/DownloadBody.kt index 5bac96a0c0..5ffb4e7983 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/model/DownloadBody.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/model/DownloadBody.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.internal.session.contentscanner.model import com.squareup.moshi.Json import com.squareup.moshi.JsonClass -import org.matrix.android.sdk.internal.crypto.model.rest.EncryptedFileInfo +import org.matrix.android.sdk.api.session.crypto.model.EncryptedFileInfo import org.matrix.android.sdk.internal.di.MoshiProvider import org.matrix.android.sdk.internal.util.JsonCanonicalizer diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/tasks/DownloadEncryptedTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/tasks/DownloadEncryptedTask.kt index f92c869cb8..abde84b6af 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/tasks/DownloadEncryptedTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/tasks/DownloadEncryptedTask.kt @@ -17,7 +17,7 @@ package org.matrix.android.sdk.internal.session.contentscanner.tasks import okhttp3.ResponseBody -import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.contentscanner.ContentScannerApiProvider import org.matrix.android.sdk.internal.session.contentscanner.ScanEncryptorUtils diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/tasks/ScanEncryptedTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/tasks/ScanEncryptedTask.kt index dab9b5538f..e098607eb6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/tasks/ScanEncryptedTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/contentscanner/tasks/ScanEncryptedTask.kt @@ -18,7 +18,7 @@ package org.matrix.android.sdk.internal.session.contentscanner.tasks import org.matrix.android.sdk.api.failure.toScanFailure import org.matrix.android.sdk.api.session.contentscanner.ScanState -import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.contentscanner.ContentScannerApiProvider import org.matrix.android.sdk.internal.session.contentscanner.ScanEncryptorUtils diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/directory/DirectoryAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/directory/DirectoryAPI.kt index 19bc7e1908..16c57baafc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/directory/DirectoryAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/directory/DirectoryAPI.kt @@ -16,9 +16,9 @@ package org.matrix.android.sdk.internal.session.directory +import org.matrix.android.sdk.api.session.room.alias.RoomAliasDescription import org.matrix.android.sdk.internal.network.NetworkConstants import org.matrix.android.sdk.internal.session.room.alias.AddRoomAliasBody -import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription import retrofit2.http.Body import retrofit2.http.DELETE import retrofit2.http.GET diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/download/ProgressResponseBody.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/download/ProgressResponseBody.kt index f4cb1a80e5..4fd4fda7d1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/download/ProgressResponseBody.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/download/ProgressResponseBody.kt @@ -24,7 +24,7 @@ import okio.ForwardingSource import okio.Source import okio.buffer -class ProgressResponseBody( +internal class ProgressResponseBody( private val responseBody: ResponseBody, private val chainUrl: String, private val progressListener: ProgressListener) : ResponseBody() { @@ -56,7 +56,7 @@ class ProgressResponseBody( } } -interface ProgressListener { +internal interface ProgressListener { fun update(url: String, bytesRead: Long, contentLength: Long, done: Boolean) fun error(url: String, errorCode: Int) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/EventFilter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/EventFilter.kt index 37630ef8ba..27a12a6145 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/EventFilter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/EventFilter.kt @@ -23,7 +23,7 @@ import com.squareup.moshi.JsonClass * https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-user-userid-filter */ @JsonClass(generateAdapter = true) -data class EventFilter( +internal data class EventFilter( /** * The maximum number of events to return. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterResponse.kt index b2d5429216..3719c803cc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/FilterResponse.kt @@ -23,7 +23,7 @@ import com.squareup.moshi.JsonClass * https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-user-userid-filter */ @JsonClass(generateAdapter = true) -data class FilterResponse( +internal data class FilterResponse( /** * Required. The ID of the filter that was created. Cannot start with a { as this character * is used to determine if the filter provided is inline JSON or a previously declared diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomEventFilter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomEventFilter.kt index 634ea73480..220c401137 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomEventFilter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomEventFilter.kt @@ -24,7 +24,7 @@ import org.matrix.android.sdk.internal.di.MoshiProvider * https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-user-userid-filter */ @JsonClass(generateAdapter = true) -data class RoomEventFilter( +internal data class RoomEventFilter( /** * The maximum number of events to return. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomFilter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomFilter.kt index 2c56a30d39..585d013eae 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomFilter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/filter/RoomFilter.kt @@ -23,7 +23,7 @@ import com.squareup.moshi.JsonClass * https://matrix.org/docs/spec/client_server/r0.3.0.html#post-matrix-client-r0-user-userid-filter */ @JsonClass(generateAdapter = true) -data class RoomFilter( +internal data class RoomFilter( /** * A list of room IDs to exclude. If this list is absent then no rooms are excluded. * A matching room will be excluded even if it is listed in the 'rooms' filter. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt index c8a9c0f09a..4285f38893 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/DefaultIdentityService.kt @@ -39,13 +39,13 @@ import org.matrix.android.sdk.api.session.identity.IdentityServiceError import org.matrix.android.sdk.api.session.identity.IdentityServiceListener import org.matrix.android.sdk.api.session.identity.SharedState import org.matrix.android.sdk.api.session.identity.ThreePid +import org.matrix.android.sdk.api.session.identity.model.SignInvitationResult import org.matrix.android.sdk.internal.di.AuthenticatedIdentity import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate import org.matrix.android.sdk.internal.extensions.observeNotNull import org.matrix.android.sdk.internal.network.RetrofitFactory import org.matrix.android.sdk.internal.session.SessionScope import org.matrix.android.sdk.internal.session.identity.data.IdentityStore -import org.matrix.android.sdk.internal.session.identity.model.SignInvitationResult import org.matrix.android.sdk.internal.session.openid.GetOpenIdTokenTask import org.matrix.android.sdk.internal.session.profile.BindThreePidsTask import org.matrix.android.sdk.internal.session.profile.UnbindThreePidsTask diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityAPI.kt index 99bd740463..7ca8758677 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/IdentityAPI.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.session.identity +import org.matrix.android.sdk.api.session.identity.model.SignInvitationResult import org.matrix.android.sdk.internal.auth.registration.SuccessResult import org.matrix.android.sdk.internal.network.NetworkConstants import org.matrix.android.sdk.internal.session.identity.model.IdentityAccountResponse @@ -26,7 +27,6 @@ import org.matrix.android.sdk.internal.session.identity.model.IdentityRequestOwn import org.matrix.android.sdk.internal.session.identity.model.IdentityRequestTokenForEmailBody import org.matrix.android.sdk.internal.session.identity.model.IdentityRequestTokenForMsisdnBody import org.matrix.android.sdk.internal.session.identity.model.IdentityRequestTokenResponse -import org.matrix.android.sdk.internal.session.identity.model.SignInvitationResult import retrofit2.http.Body import retrofit2.http.GET import retrofit2.http.POST diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/Sign3pidInvitationTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/Sign3pidInvitationTask.kt index d491af33ca..06a6cecc05 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/Sign3pidInvitationTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/Sign3pidInvitationTask.kt @@ -18,10 +18,10 @@ package org.matrix.android.sdk.internal.session.identity import dagger.Lazy import okhttp3.OkHttpClient +import org.matrix.android.sdk.api.session.identity.model.SignInvitationResult import org.matrix.android.sdk.internal.di.Unauthenticated import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.network.RetrofitFactory -import org.matrix.android.sdk.internal.session.identity.model.SignInvitationResult import org.matrix.android.sdk.internal.task.Task import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/migration/MigrateIdentityTo001.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/migration/MigrateIdentityTo001.kt index 002601470d..17a23b828a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/migration/MigrateIdentityTo001.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/identity/db/migration/MigrateIdentityTo001.kt @@ -21,7 +21,7 @@ import org.matrix.android.sdk.internal.session.identity.db.IdentityDataEntityFie import org.matrix.android.sdk.internal.util.database.RealmMigrator import timber.log.Timber -class MigrateIdentityTo001(realm: DynamicRealm) : RealmMigrator(realm, 1) { +internal class MigrateIdentityTo001(realm: DynamicRealm) : RealmMigrator(realm, 1) { override fun doMigrate(realm: DynamicRealm) { Timber.d("Add field userConsent (Boolean) and set the value to false") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultSyncStatusService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultSyncStatusService.kt index 079b0d0115..4a1e6661b0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultSyncStatusService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/initsync/DefaultSyncStatusService.kt @@ -72,7 +72,7 @@ internal class DefaultSyncStatusService @Inject constructor() : // Update the progress of the leaf and all its parents leaf.setProgress(progress) // Then update the live data using leaf wording and root progress - status.postValue(SyncStatusService.Status.Progressing(leaf.initSyncStep, root.currentProgress.toInt())) + status.postValue(SyncStatusService.Status.InitialSyncProgressing(leaf.initSyncStep, root.currentProgress.toInt())) } } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt index 8ae203c2b3..899bce4c8d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/notification/ProcessEventForPushTask.kt @@ -57,6 +57,7 @@ internal class DefaultProcessEventForPushTask @Inject constructor( val allEvents = (newJoinEvents + inviteEvents).filter { event -> when (event.type) { in EventType.POLL_START, + in EventType.STATE_ROOM_BEACON_INFO, EventType.MESSAGE, EventType.REDACTION, EventType.ENCRYPTED, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/model/GetPresenceResponse.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/model/GetPresenceResponse.kt index a7552f7b02..1cd6d7d3f2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/model/GetPresenceResponse.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/model/GetPresenceResponse.kt @@ -21,7 +21,7 @@ import com.squareup.moshi.JsonClass import org.matrix.android.sdk.api.session.presence.model.PresenceEnum @JsonClass(generateAdapter = true) -data class GetPresenceResponse( +internal data class GetPresenceResponse( @Json(name = "presence") val presence: PresenceEnum, @Json(name = "last_active_ago") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/model/PresenceContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/model/PresenceContent.kt index 45e0fcf06e..b1ca512652 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/model/PresenceContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/model/PresenceContent.kt @@ -24,7 +24,7 @@ import org.matrix.android.sdk.api.session.presence.model.PresenceEnum * Class representing the EventType.PRESENCE event content */ @JsonClass(generateAdapter = true) -data class PresenceContent( +internal data class PresenceContent( /** * Required. The presence state for this user. One of: ["online", "offline", "unavailable"] */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/service/DefaultPresenceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/service/DefaultPresenceService.kt index 1083d5b4c2..ca89ef684f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/service/DefaultPresenceService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/presence/service/DefaultPresenceService.kt @@ -23,15 +23,19 @@ import org.matrix.android.sdk.api.session.presence.model.UserPresence import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.presence.service.task.GetPresenceTask import org.matrix.android.sdk.internal.session.presence.service.task.SetPresenceTask +import org.matrix.android.sdk.internal.session.sync.SyncPresence +import org.matrix.android.sdk.internal.settings.DefaultLightweightSettingsStorage import javax.inject.Inject internal class DefaultPresenceService @Inject constructor( @UserId private val userId: String, private val setPresenceTask: SetPresenceTask, - private val getPresenceTask: GetPresenceTask + private val getPresenceTask: GetPresenceTask, + private val lightweightSettingsStorage: DefaultLightweightSettingsStorage ) : PresenceService { override suspend fun setMyPresence(presence: PresenceEnum, statusMsg: String?) { + lightweightSettingsStorage.setSyncPresenceStatus(SyncPresence.from(presence)) setPresenceTask.execute(SetPresenceTask.Params(userId, presence, statusMsg)) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/BindThreePidBody.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/BindThreePidBody.kt index fa45ae9940..4d2a999137 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/BindThreePidBody.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/profile/BindThreePidBody.kt @@ -30,17 +30,17 @@ internal data class BindThreePidBody( * Required. The identity server to use. (without "https://") */ @Json(name = "id_server") - var identityServerUrlWithoutProtocol: String, + val identityServerUrlWithoutProtocol: String, /** * Required. An access token previously registered with the identity server. */ @Json(name = "id_access_token") - var identityServerAccessToken: String, + val identityServerAccessToken: String, /** * Required. The session identifier given by the identity server. */ @Json(name = "sid") - var sid: String + val sid: String ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt index 34e859e509..3f129c4d71 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoom.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.room import androidx.lifecycle.LiveData import org.matrix.android.sdk.api.MatrixCoroutineDispatchers +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.room.Room @@ -44,13 +45,12 @@ import org.matrix.android.sdk.api.session.room.version.RoomVersionService import org.matrix.android.sdk.api.session.search.SearchResult import org.matrix.android.sdk.api.session.space.Space import org.matrix.android.sdk.api.util.Optional -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM +import org.matrix.android.sdk.api.util.awaitCallback import org.matrix.android.sdk.internal.session.permalinks.ViaParameterFinder import org.matrix.android.sdk.internal.session.room.state.SendStateTask import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource import org.matrix.android.sdk.internal.session.search.SearchTask import org.matrix.android.sdk.internal.session.space.DefaultSpace -import org.matrix.android.sdk.internal.util.awaitCallback import java.security.InvalidParameterException internal class DefaultRoom(override val roomId: String, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt index c79c41069b..8424ee8a36 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/DefaultRoomService.kt @@ -22,11 +22,13 @@ import androidx.paging.PagedList import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.identity.model.SignInvitationResult import org.matrix.android.sdk.api.session.room.Room import org.matrix.android.sdk.api.session.room.RoomService import org.matrix.android.sdk.api.session.room.RoomSortOrder import org.matrix.android.sdk.api.session.room.RoomSummaryQueryParams import org.matrix.android.sdk.api.session.room.UpdatableLivePageResult +import org.matrix.android.sdk.api.session.room.alias.RoomAliasDescription import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary @@ -40,10 +42,8 @@ import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.database.model.RoomMemberSummaryEntityFields import org.matrix.android.sdk.internal.di.SessionDatabase -import org.matrix.android.sdk.internal.session.identity.model.SignInvitationResult import org.matrix.android.sdk.internal.session.room.alias.DeleteRoomAliasTask import org.matrix.android.sdk.internal.session.room.alias.GetRoomIdByAliasTask -import org.matrix.android.sdk.internal.session.room.alias.RoomAliasDescription import org.matrix.android.sdk.internal.session.room.create.CreateRoomTask import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource import org.matrix.android.sdk.internal.session.room.membership.RoomMemberHelper diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt index 8bbe3a9ac6..15ce5810c8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt @@ -16,14 +16,15 @@ package org.matrix.android.sdk.internal.session.room import io.realm.Realm -import org.matrix.android.sdk.api.crypto.VerificationState import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.query.QueryStringValue +import org.matrix.android.sdk.api.session.crypto.verification.VerificationState import org.matrix.android.sdk.api.session.events.model.AggregatedAnnotation import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.LocalEcho import org.matrix.android.sdk.api.session.events.model.RelationType +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent import org.matrix.android.sdk.api.session.events.model.getRelationContent import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.events.model.toModel @@ -34,6 +35,7 @@ import org.matrix.android.sdk.api.session.room.model.VoteInfo import org.matrix.android.sdk.api.session.room.model.VoteSummary import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessageEndPollContent +import org.matrix.android.sdk.api.session.room.model.message.MessageLiveLocationContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponseContent import org.matrix.android.sdk.api.session.room.model.message.MessageRelationContent @@ -42,7 +44,6 @@ import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent import org.matrix.android.sdk.internal.SessionManager -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent import org.matrix.android.sdk.internal.crypto.verification.toState import org.matrix.android.sdk.internal.database.helper.findRootThreadEvent import org.matrix.android.sdk.internal.database.mapper.ContentMapper @@ -64,6 +65,7 @@ import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.EventInsertLiveProcessor +import org.matrix.android.sdk.internal.session.room.aggregation.livelocation.LiveLocationAggregationProcessor import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource import timber.log.Timber import javax.inject.Inject @@ -72,7 +74,8 @@ internal class EventRelationsAggregationProcessor @Inject constructor( @UserId private val userId: String, private val stateEventDataSource: StateEventDataSource, @SessionId private val sessionId: String, - private val sessionManager: SessionManager + private val sessionManager: SessionManager, + private val liveLocationAggregationProcessor: LiveLocationAggregationProcessor ) : EventInsertLiveProcessor { private val allowedTypes = listOf( @@ -88,7 +91,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor( // EventType.KEY_VERIFICATION_READY, EventType.KEY_VERIFICATION_KEY, EventType.ENCRYPTED - ) + EventType.POLL_START + EventType.POLL_RESPONSE + EventType.POLL_END + ) + EventType.POLL_START + EventType.POLL_RESPONSE + EventType.POLL_END + EventType.BEACON_LOCATION_DATA override fun shouldProcess(eventId: String, eventType: String, insertType: EventInsertType): Boolean { return allowedTypes.contains(eventType) @@ -103,12 +106,12 @@ internal class EventRelationsAggregationProcessor @Inject constructor( } val isLocalEcho = LocalEcho.isLocalEchoId(event.eventId ?: "") when (event.type) { - EventType.REACTION -> { + EventType.REACTION -> { // we got a reaction!! Timber.v("###REACTION in room $roomId , reaction eventID ${event.eventId}") handleReaction(realm, event, roomId, isLocalEcho) } - EventType.MESSAGE -> { + EventType.MESSAGE -> { if (event.unsignedData?.relations?.annotations != null) { Timber.v("###REACTION Aggregation in room $roomId for event ${event.eventId}") handleInitialAggregatedRelations(realm, event, roomId, event.unsignedData.relations.annotations) @@ -134,7 +137,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor( EventType.KEY_VERIFICATION_START, EventType.KEY_VERIFICATION_MAC, EventType.KEY_VERIFICATION_READY, - EventType.KEY_VERIFICATION_KEY -> { + EventType.KEY_VERIFICATION_KEY -> { Timber.v("## SAS REF in room $roomId for event ${event.eventId}") event.content.toModel<MessageRelationContent>()?.relatesTo?.let { if (it.type == RelationType.REFERENCE && it.eventId != null) { @@ -143,7 +146,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor( } } - EventType.ENCRYPTED -> { + EventType.ENCRYPTED -> { // Relation type is in clear val encryptedEventContent = event.content.toModel<EncryptedEventContent>() if (encryptedEventContent?.relatesTo?.type == RelationType.REPLACE || @@ -169,22 +172,27 @@ internal class EventRelationsAggregationProcessor @Inject constructor( EventType.KEY_VERIFICATION_START, EventType.KEY_VERIFICATION_MAC, EventType.KEY_VERIFICATION_READY, - EventType.KEY_VERIFICATION_KEY -> { + EventType.KEY_VERIFICATION_KEY -> { Timber.v("## SAS REF in room $roomId for event ${event.eventId}") encryptedEventContent.relatesTo.eventId?.let { handleVerification(realm, event, roomId, isLocalEcho, it) } } - in EventType.POLL_RESPONSE -> { + in EventType.POLL_RESPONSE -> { event.getClearContent().toModel<MessagePollResponseContent>(catchError = true)?.let { handleResponse(realm, event, it, roomId, isLocalEcho, event.getRelationContent()?.eventId) } } - in EventType.POLL_END -> { + in EventType.POLL_END -> { event.content.toModel<MessageEndPollContent>(catchError = true)?.let { handleEndPoll(realm, event, it, roomId, isLocalEcho) } } + in EventType.BEACON_LOCATION_DATA -> { + event.content.toModel<MessageLiveLocationContent>(catchError = true)?.let { + liveLocationAggregationProcessor.handleLiveLocation(realm, event, it, roomId, isLocalEcho) + } + } } } else if (encryptedEventContent?.relatesTo?.type == RelationType.ANNOTATION) { // Reaction @@ -205,7 +213,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor( // } // } } - EventType.REDACTION -> { + EventType.REDACTION -> { val eventToPrune = event.redacts?.let { EventEntity.where(realm, eventId = it).findFirst() } ?: return when (eventToPrune.type) { @@ -225,7 +233,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor( } } } - in EventType.POLL_START -> { + in EventType.POLL_START -> { val content: MessagePollContent? = event.content.toModel() if (content?.relatesTo?.type == RelationType.REPLACE) { Timber.v("###REPLACE in room $roomId for event ${event.eventId}") @@ -233,17 +241,22 @@ internal class EventRelationsAggregationProcessor @Inject constructor( handleReplace(realm, event, content, roomId, isLocalEcho) } } - in EventType.POLL_RESPONSE -> { + in EventType.POLL_RESPONSE -> { event.content.toModel<MessagePollResponseContent>(catchError = true)?.let { handleResponse(realm, event, it, roomId, isLocalEcho) } } - in EventType.POLL_END -> { + in EventType.POLL_END -> { event.content.toModel<MessageEndPollContent>(catchError = true)?.let { handleEndPoll(realm, event, it, roomId, isLocalEcho) } } - else -> Timber.v("UnHandled event ${event.eventId}") + in EventType.BEACON_LOCATION_DATA -> { + event.content.toModel<MessageLiveLocationContent>(catchError = true)?.let { + liveLocationAggregationProcessor.handleLiveLocation(realm, event, it, roomId, isLocalEcho) + } + } + else -> Timber.v("UnHandled event ${event.eventId}") } } catch (t: Throwable) { Timber.e(t, "## Should not happen ") @@ -303,14 +316,16 @@ internal class EventRelationsAggregationProcessor @Inject constructor( ContentMapper .map(eventAnnotationsSummaryEntity.pollResponseSummary?.aggregatedContent) ?.toModel<PollSummaryContent>() - ?.apply { - totalVotes = 0 - winnerVoteCount = 0 - votes = emptyList() - votesSummary = emptyMap() - } - ?.apply { - eventAnnotationsSummaryEntity.pollResponseSummary?.aggregatedContent = ContentMapper.map(toContent()) + ?.let { existingPollSummaryContent -> + eventAnnotationsSummaryEntity.pollResponseSummary?.aggregatedContent = ContentMapper.map( + PollSummaryContent( + myVote = existingPollSummaryContent.myVote, + votes = emptyList(), + votesSummary = emptyMap(), + totalVotes = 0, + winnerVoteCount = 0, + ) + .toContent()) } val txId = event.unsignedData?.transactionId @@ -397,15 +412,15 @@ internal class EventRelationsAggregationProcessor @Inject constructor( existing.pollResponseSummary = it } - val closedTime = existingPollSummary?.closedTime + val closedTime = existingPollSummary.closedTime if (closedTime != null && eventTimestamp > closedTime) { Timber.v("## POLL is closed ignore event poll:$targetEventId, event :${event.eventId}") return } - val sumModel = ContentMapper.map(existingPollSummary?.aggregatedContent).toModel<PollSummaryContent>() ?: PollSummaryContent() + val currentModel = ContentMapper.map(existingPollSummary.aggregatedContent).toModel<PollSummaryContent>() - if (existingPollSummary!!.sourceEvents.contains(eventId)) { + if (existingPollSummary.sourceEvents.contains(eventId)) { // ignore this event, we already know it (??) Timber.v("## POLL ignoring event for summary, it's known eventId:$eventId") return @@ -430,7 +445,9 @@ internal class EventRelationsAggregationProcessor @Inject constructor( return } - val votes = sumModel.votes?.toMutableList() ?: ArrayList() + val votes = currentModel?.votes.orEmpty().toMutableList() + + var myVote: String? = null val existingVoteIndex = votes.indexOfFirst { it.userId == senderId } if (existingVoteIndex != -1) { // Is the vote newer? @@ -439,7 +456,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor( // Take the new one votes[existingVoteIndex] = VoteInfo(senderId, option, eventTimestamp) if (userId == senderId) { - sumModel.myVote = option + myVote = option } Timber.v("## POLL adding vote $option for user $senderId in poll :$targetEventId ") } else { @@ -448,16 +465,14 @@ internal class EventRelationsAggregationProcessor @Inject constructor( } else { votes.add(VoteInfo(senderId, option, eventTimestamp)) if (userId == senderId) { - sumModel.myVote = option + myVote = option } Timber.v("## POLL adding vote $option for user $senderId in poll :$targetEventId ") } - sumModel.votes = votes // Precompute the percentage of votes for all options val totalVotes = votes.size - sumModel.totalVotes = totalVotes - sumModel.votesSummary = votes + val newVotesSummary = votes .groupBy({ it.option }, { it.userId }) .mapValues { VoteSummary( @@ -465,7 +480,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor( percentage = if (totalVotes == 0 && it.value.isEmpty()) 0.0 else it.value.size.toDouble() / totalVotes ) } - sumModel.winnerVoteCount = sumModel.votesSummary?.maxOf { it.value.total } ?: 0 + val newWinnerVoteCount = newVotesSummary.maxOf { it.value.total } if (isLocalEcho) { existingPollSummary.sourceLocalEchoEvents.add(eventId) @@ -473,7 +488,15 @@ internal class EventRelationsAggregationProcessor @Inject constructor( existingPollSummary.sourceEvents.add(eventId) } - existingPollSummary.aggregatedContent = ContentMapper.map(sumModel.toContent()) + val newSumModel = PollSummaryContent( + myVote = myVote, + votes = votes, + votesSummary = newVotesSummary, + totalVotes = totalVotes, + winnerVoteCount = newWinnerVoteCount + ) + + existingPollSummary.aggregatedContent = ContentMapper.map(newSumModel.toContent()) } private fun handleEndPoll(realm: Realm, @@ -584,11 +607,11 @@ internal class EventRelationsAggregationProcessor @Inject constructor( sum.key = reaction sum.firstTimestamp = event.originServerTs ?: 0 if (isLocalEcho) { - Timber.v("Adding local echo reaction $reaction") + Timber.v("Adding local echo reaction") sum.sourceLocalEcho.add(txId) sum.count = 1 } else { - Timber.v("Adding synced reaction $reaction") + Timber.v("Adding synced reaction") sum.count = 1 sum.sourceEvents.add(reactionEventId) } @@ -600,16 +623,16 @@ internal class EventRelationsAggregationProcessor @Inject constructor( // check if it's not the sync of a local echo if (!isLocalEcho && sum.sourceLocalEcho.contains(txId)) { // ok it has already been counted, just sync the list, do not touch count - Timber.v("Ignoring synced of local echo for reaction $reaction") + Timber.v("Ignoring synced of local echo for reaction") sum.sourceLocalEcho.remove(txId) sum.sourceEvents.add(reactionEventId) } else { sum.count += 1 if (isLocalEcho) { - Timber.v("Adding local echo reaction $reaction") + Timber.v("Adding local echo reaction") sum.sourceLocalEcho.add(txId) } else { - Timber.v("Adding synced reaction $reaction") + Timber.v("Adding synced reaction") sum.sourceEvents.add(reactionEventId) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DefaultLiveLocationAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DefaultLiveLocationAggregationProcessor.kt new file mode 100644 index 0000000000..95e196c762 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/DefaultLiveLocationAggregationProcessor.kt @@ -0,0 +1,85 @@ +/* + * Copyright 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.aggregation.livelocation + +import io.realm.Realm +import org.matrix.android.sdk.api.extensions.orFalse +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.toContent +import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationBeaconContent +import org.matrix.android.sdk.api.session.room.model.message.MessageLiveLocationContent +import org.matrix.android.sdk.internal.database.mapper.ContentMapper +import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity +import org.matrix.android.sdk.internal.database.query.getOrNull +import timber.log.Timber +import javax.inject.Inject + +internal class DefaultLiveLocationAggregationProcessor @Inject constructor() : LiveLocationAggregationProcessor { + + override fun handleLiveLocation(realm: Realm, event: Event, content: MessageLiveLocationContent, roomId: String, isLocalEcho: Boolean) { + val locationSenderId = event.senderId ?: return + + // We shouldn't process local echos + if (isLocalEcho) { + return + } + + // A beacon info state event has to be sent before sending location + // TODO handle missing check of m_relatesTo field + var beaconInfoEntity: CurrentStateEventEntity? = null + val eventTypesIterator = EventType.STATE_ROOM_BEACON_INFO.iterator() + while (beaconInfoEntity == null && eventTypesIterator.hasNext()) { + beaconInfoEntity = CurrentStateEventEntity.getOrNull(realm, roomId, locationSenderId, eventTypesIterator.next()) + } + + if (beaconInfoEntity == null) { + Timber.v("## LIVE LOCATION. There is not any beacon info which should be emitted before sending location updates") + return + } + val beaconInfoContent = ContentMapper.map(beaconInfoEntity.root?.content)?.toModel<LiveLocationBeaconContent>(catchError = true) + if (beaconInfoContent == null) { + Timber.v("## LIVE LOCATION. Beacon info content is invalid") + return + } + + // Check if live location is ended + if (!beaconInfoContent.getBestBeaconInfo()?.isLive.orFalse()) { + Timber.v("## LIVE LOCATION. Beacon info is not live anymore") + return + } + + // Check if beacon info is outdated + if (isBeaconInfoOutdated(beaconInfoContent, content)) { + Timber.v("## LIVE LOCATION. Beacon info has timeout") + beaconInfoContent.hasTimedOut = true + } else { + beaconInfoContent.lastLocationContent = content + } + + beaconInfoEntity.root?.content = ContentMapper.map(beaconInfoContent.toContent()) + } + + private fun isBeaconInfoOutdated(beaconInfoContent: LiveLocationBeaconContent, + liveLocationContent: MessageLiveLocationContent): Boolean { + val beaconInfoStartTime = beaconInfoContent.getBestTimestampAsMilliseconds() ?: 0 + val liveLocationEventTime = liveLocationContent.getBestTimestampAsMilliseconds() ?: 0 + val timeout = beaconInfoContent.getBestBeaconInfo()?.timeout ?: 0 + return liveLocationEventTime - beaconInfoStartTime > timeout + } +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt new file mode 100644 index 0000000000..7b5f23e243 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/aggregation/livelocation/LiveLocationAggregationProcessor.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.matrix.android.sdk.internal.session.room.aggregation.livelocation + +import io.realm.Realm +import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.room.model.message.MessageLiveLocationContent + +internal interface LiveLocationAggregationProcessor { + fun handleLiveLocation(realm: Realm, + event: Event, + content: MessageLiveLocationContent, + roomId: String, + isLocalEcho: Boolean) +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt index 71c8c9cd38..dc3ea55a01 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/alias/GetRoomIdByAliasTask.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.room.alias import com.zhuinden.monarchy.Monarchy import io.realm.Realm import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.session.room.alias.RoomAliasDescription import org.matrix.android.sdk.api.util.Optional import org.matrix.android.sdk.internal.database.model.RoomSummaryEntity import org.matrix.android.sdk.internal.database.query.findByAlias diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt index c9914449c3..3b2e9d3d22 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/create/CreateRoomBodyBuilder.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.session.room.create +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType @@ -24,7 +25,6 @@ import org.matrix.android.sdk.api.session.identity.toMedium import org.matrix.android.sdk.api.session.room.model.create.CreateRoomParams import org.matrix.android.sdk.api.util.MimeTypes import org.matrix.android.sdk.internal.crypto.DeviceListManager -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.internal.di.AuthenticatedIdentity import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.network.token.AccessTokenProvider diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt index 15e804d69e..fd35ddd0c3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/LoadRoomMembersTask.kt @@ -123,7 +123,7 @@ internal class DefaultLoadRoomMembersTask @Inject constructor( eventId = roomMemberEvent.eventId root = eventEntity } - roomMemberEventHandler.handle(realm, roomId, roomMemberEvent) + roomMemberEventHandler.handle(realm, roomId, roomMemberEvent, false) } roomEntity.membersLoadStatus = RoomMembersLoadStatusType.LOADED roomSummaryUpdater.update(realm, roomId, updateMembers = true, updateCounts = false) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt index 25c124bd6b..85300fa351 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/RoomMemberEventHandler.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.membership import io.realm.Realm +import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.room.model.RoomMemberContent @@ -33,23 +34,49 @@ internal class RoomMemberEventHandler @Inject constructor( @UserId private val myUserId: String ) { - fun handle(realm: Realm, roomId: String, event: Event, aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { + fun handle(realm: Realm, + roomId: String, + event: Event, + isInitialSync: Boolean, + aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { if (event.type != EventType.STATE_ROOM_MEMBER) { return false } - val userId = event.stateKey ?: return false - val roomMember = event.getFixedRoomMemberContent() - return handle(realm, roomId, userId, roomMember, aggregator) + val eventUserId = event.stateKey ?: return false + val roomMember = event.getFixedRoomMemberContent() ?: return false + + return if (isInitialSync) { + handleInitialSync(realm, roomId, myUserId, eventUserId, roomMember, aggregator) + } else { + handleIncrementalSync( + realm, + roomId, + eventUserId, + roomMember, + event.resolvedPrevContent(), + aggregator + ) + } } - fun handle(realm: Realm, - roomId: String, - userId: String, - roomMember: RoomMemberContent?, - aggregator: SyncResponsePostTreatmentAggregator? = null): Boolean { - if (roomMember == null) { - return false + private fun handleInitialSync(realm: Realm, + roomId: String, + currentUserId: String, + eventUserId: String, + roomMember: RoomMemberContent, + aggregator: SyncResponsePostTreatmentAggregator?): Boolean { + if (currentUserId != eventUserId) { + saveUserEntityLocallyIfNecessary(realm, eventUserId, roomMember) } + saveRoomMemberEntityLocally(realm, roomId, eventUserId, roomMember) + updateDirectChatsIfNecessary(roomId, roomMember, aggregator) + return true + } + + private fun saveRoomMemberEntityLocally(realm: Realm, + roomId: String, + userId: String, + roomMember: RoomMemberContent) { val roomMemberEntity = RoomMemberEntityFactory.create( roomId, userId, @@ -58,26 +85,58 @@ internal class RoomMemberEventHandler @Inject constructor( // but we want to preserve presence record value and not replace it with null getExistingPresenceState(realm, roomId, userId)) realm.insertOrUpdate(roomMemberEntity) - if (roomMember.membership.isActive()) { - val userEntity = UserEntityFactory.create(userId, roomMember) - realm.insertOrUpdate(userEntity) - } - - // check whether this new room member event may be used to update the directs dictionary in account data - // this is required to handle correctly invite by email in DM - val mxId = roomMember.thirdPartyInvite?.signed?.mxid - if (mxId != null && mxId != myUserId) { - aggregator?.directChatsToCheck?.put(roomId, mxId) - } - return true } /** * Get the already existing presence state for a specific user & room in order NOT to be replaced in RoomMemberSummaryEntity * by NULL value. */ - private fun getExistingPresenceState(realm: Realm, roomId: String, userId: String): UserPresenceEntity? { return RoomMemberSummaryEntity.where(realm, roomId, userId).findFirst()?.userPresenceEntity } + + private fun saveUserEntityLocallyIfNecessary(realm: Realm, + userId: String, + roomMember: RoomMemberContent) { + if (roomMember.membership.isActive()) { + saveUserLocally(realm, userId, roomMember) + } + } + + private fun saveUserLocally(realm: Realm, userId: String, roomMember: RoomMemberContent) { + val userEntity = UserEntityFactory.create(userId, roomMember) + realm.insertOrUpdate(userEntity) + } + + private fun updateDirectChatsIfNecessary(roomId: String, + roomMember: RoomMemberContent, + aggregator: SyncResponsePostTreatmentAggregator?) { + // check whether this new room member event may be used to update the directs dictionary in account data + // this is required to handle correctly invite by email in DM + val mxId = roomMember.thirdPartyInvite?.signed?.mxid + if (mxId != null && mxId != myUserId) { + aggregator?.directChatsToCheck?.put(roomId, mxId) + } + } + + private fun handleIncrementalSync(realm: Realm, + roomId: String, + eventUserId: String, + roomMember: RoomMemberContent, + prevContent: Content?, + aggregator: SyncResponsePostTreatmentAggregator?): Boolean { + if (aggregator != null) { + val previousDisplayName = prevContent?.get("displayname") as? String + val previousAvatar = prevContent?.get("avatar_url") as? String + + if (previousDisplayName != roomMember.displayName || previousAvatar != roomMember.avatarUrl) { + aggregator.userIdsToFetch.add(eventUserId) + } + } + + saveRoomMemberEntityLocally(realm, roomId, eventUserId, roomMember) + // At the end of the sync, fetch all the profiles from the aggregator + updateDirectChatsIfNecessary(roomId, roomMember, aggregator) + return true + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/InviteBody.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/InviteBody.kt index 06b75709a2..300cc210bc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/InviteBody.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/InviteBody.kt @@ -20,7 +20,7 @@ import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -data class InviteBody( +internal data class InviteBody( @Json(name = "user_id") val userId: String, @Json(name = "reason") val reason: String? ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt index 22a46b6cfc..f883cc33ec 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/membership/joining/JoinRoomTask.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.room.membership.joining import io.realm.RealmConfiguration import kotlinx.coroutines.TimeoutCancellationException import org.matrix.android.sdk.api.session.events.model.toContent +import org.matrix.android.sdk.api.session.identity.model.SignInvitationResult import org.matrix.android.sdk.api.session.room.failure.JoinRoomFailure import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.Membership @@ -30,7 +31,6 @@ import org.matrix.android.sdk.internal.database.query.where import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest -import org.matrix.android.sdk.internal.session.identity.model.SignInvitationResult import org.matrix.android.sdk.internal.session.room.RoomAPI import org.matrix.android.sdk.internal.session.room.membership.RoomChangeMembershipStateDataSource import org.matrix.android.sdk.internal.session.room.read.SetReadMarkersTask diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/prune/RedactionEventProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/prune/RedactionEventProcessor.kt index b19b8d4a6b..fe7dc28228 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/prune/RedactionEventProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/prune/RedactionEventProcessor.kt @@ -86,9 +86,9 @@ internal class RedactionEventProcessor @Inject constructor() : EventInsertLivePr // } val modified = unsignedData.copy(redactedEvent = redactionEvent) - // I Commented the line below, it should not be empty while we lose all the previous info about - // the redacted event -// eventToPrune.content = ContentMapper.map(emptyMap()) + // Deleting the content of a thread message will result to delete the thread relation, however threads are now dynamic + // so there is not much of a problem + eventToPrune.content = ContentMapper.map(emptyMap()) eventToPrune.unsignedData = MoshiProvider.providesMoshi().adapter(UnsignedData::class.java).toJson(modified) eventToPrune.decryptionResultJson = null eventToPrune.decryptionErrorCode = null diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/FullyReadContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/FullyReadContent.kt index 9b4db795ec..00dfe6d29c 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/FullyReadContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/read/FullyReadContent.kt @@ -20,6 +20,6 @@ import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -data class FullyReadContent( +internal data class FullyReadContent( @Json(name = "event_id") val eventId: String ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/threads/FetchThreadTimelineTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/threads/FetchThreadTimelineTask.kt index a46bbe8d9f..116d4aa0a1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/threads/FetchThreadTimelineTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/threads/FetchThreadTimelineTask.kt @@ -18,13 +18,13 @@ package org.matrix.android.sdk.internal.session.room.relation.threads import com.zhuinden.monarchy.Monarchy import io.realm.Realm import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.internal.crypto.CryptoSessionInfoProvider import org.matrix.android.sdk.internal.crypto.DefaultCryptoService -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.database.helper.addTimelineEvent import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.database.mapper.toEntity @@ -251,7 +251,7 @@ internal class DefaultFetchThreadTimelineTask @Inject constructor( sum = realm.createObject(ReactionAggregatedSummaryEntity::class.java) sum.key = reaction sum.firstTimestamp = event.originServerTs ?: 0 - Timber.v("Adding synced reaction $reaction") + Timber.v("Adding synced reaction") sum.count = 1 // reactionEventId not included in the /relations API // sum.sourceEvents.add(reactionEventId) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt index 31c7254ed5..34e38581d1 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/DefaultSendService.kt @@ -46,6 +46,7 @@ import org.matrix.android.sdk.api.util.Cancelable import org.matrix.android.sdk.api.util.CancelableBag import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.api.util.NoOpCancellable +import org.matrix.android.sdk.api.util.TextContent import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.WorkManagerProvider @@ -134,6 +135,12 @@ internal class DefaultSendService @AssistedInject constructor( .let { sendEvent(it) } } + override fun sendLiveLocation(beaconInfoEventId: String, latitude: Double, longitude: Double, uncertainty: Double?): Cancelable { + return localEchoEventFactory.createLiveLocationEvent(beaconInfoEventId, roomId, latitude, longitude, uncertainty) + .also { createLocalEcho(it) } + .let { sendEvent(it) } + } + override fun redactEvent(event: Event, reason: String?): Cancelable { // TODO manage media/attachements? val redactionEcho = localEchoEventFactory.createRedactEvent(roomId, event.eventId!!, reason) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt index 82116cd177..119d32d720 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/LocalEchoEventFactory.kt @@ -43,6 +43,7 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageEndPollConte import org.matrix.android.sdk.api.session.room.model.message.MessageFileContent import org.matrix.android.sdk.api.session.room.model.message.MessageFormat import org.matrix.android.sdk.api.session.room.model.message.MessageImageContent +import org.matrix.android.sdk.api.session.room.model.message.MessageLiveLocationContent import org.matrix.android.sdk.api.session.room.model.message.MessageLocationContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollContent import org.matrix.android.sdk.api.session.room.model.message.MessagePollResponseContent @@ -64,6 +65,7 @@ import org.matrix.android.sdk.api.session.room.model.relation.ReplyToContent import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent import org.matrix.android.sdk.api.session.room.timeline.isReply +import org.matrix.android.sdk.api.util.TextContent import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.content.ThumbnailExtractor import org.matrix.android.sdk.internal.session.permalinks.PermalinkFactory @@ -243,6 +245,32 @@ internal class LocalEchoEventFactory @Inject constructor( return createMessageEvent(roomId, content) } + fun createLiveLocationEvent(beaconInfoEventId: String, + roomId: String, + latitude: Double, + longitude: Double, + uncertainty: Double?): Event { + val geoUri = buildGeoUri(latitude, longitude, uncertainty) + val content = MessageLiveLocationContent( + body = geoUri, + relatesTo = RelationDefaultContent( + type = RelationType.REFERENCE, + eventId = beaconInfoEventId + ), + unstableLocationInfo = LocationInfo(geoUri = geoUri, description = geoUri), + unstableTimestampAsMilliseconds = TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()), + ) + val localId = LocalEcho.createLocalEchoId() + return Event( + roomId = roomId, + originServerTs = dummyOriginServerTs(), + senderId = userId, + eventId = localId, + type = EventType.BEACON_LOCATION_DATA.first(), + content = content.toContent(), + unsignedData = UnsignedData(age = null, transactionId = localId)) + } + fun createReplaceTextOfReply(roomId: String, eventReplaced: TimelineEvent, originalEvent: TimelineEvent, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MarkdownParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MarkdownParser.kt index ef7945cf8c..05585a4cb5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MarkdownParser.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MarkdownParser.kt @@ -18,6 +18,7 @@ package org.matrix.android.sdk.internal.session.room.send import org.commonmark.parser.Parser import org.commonmark.renderer.html.HtmlRenderer +import org.matrix.android.sdk.api.util.TextContent import org.matrix.android.sdk.internal.session.room.AdvancedCommonmarkParser import org.matrix.android.sdk.internal.session.room.SimpleCommonmarkParser import org.matrix.android.sdk.internal.session.room.send.pills.TextPillsUtils diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt index f44c255f1e..b59f1b174f 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/MultipleEventSendingDispatcherWorker.kt @@ -29,7 +29,6 @@ import org.matrix.android.sdk.internal.session.room.timeline.TimelineSendEventWo import org.matrix.android.sdk.internal.worker.SessionSafeCoroutineWorker import org.matrix.android.sdk.internal.worker.SessionWorkerParams import org.matrix.android.sdk.internal.worker.WorkerParamsFactory -import org.matrix.android.sdk.internal.worker.startChain import timber.log.Timber import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/TextContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/TextContentExtension.kt similarity index 86% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/TextContent.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/TextContentExtension.kt index 93c0167abe..8caa99d90a 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/TextContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/send/TextContentExtension.kt @@ -24,18 +24,9 @@ import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultCon import org.matrix.android.sdk.api.session.room.model.relation.ReplyToContent import org.matrix.android.sdk.api.util.ContentUtils.extractUsefulTextFromHtmlReply import org.matrix.android.sdk.api.util.ContentUtils.extractUsefulTextFromReply +import org.matrix.android.sdk.api.util.TextContent -/** - * Contains a text and eventually a formatted text - */ -data class TextContent( - val text: String, - val formattedText: String? = null -) { - fun takeFormatted() = formattedText ?: text -} - -fun TextContent.toMessageTextContent(msgType: String = MessageType.MSGTYPE_TEXT): MessageTextContent { +internal fun TextContent.toMessageTextContent(msgType: String = MessageType.MSGTYPE_TEXT): MessageTextContent { return MessageTextContent( msgType = msgType, format = MessageFormat.FORMAT_MATRIX_HTML.takeIf { formattedText != null }, @@ -49,7 +40,7 @@ fun TextContent.toMessageTextContent(msgType: String = MessageType.MSGTYPE_TEXT) * latestThreadEventId in order for the clients without threads enabled to render it appropriately * If latest event not found, we pass rootThreadEventId */ -fun TextContent.toThreadTextContent( +internal fun TextContent.toThreadTextContent( rootThreadEventId: String, latestThreadEventId: String, msgType: String = MessageType.MSGTYPE_TEXT): MessageTextContent { @@ -68,7 +59,7 @@ fun TextContent.toThreadTextContent( ) } -fun TextContent.removeInReplyFallbacks(): TextContent { +internal fun TextContent.removeInReplyFallbacks(): TextContent { return copy( text = extractUsefulTextFromReply(this.text), formattedText = this.formattedText?.let { extractUsefulTextFromHtmlReply(it) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt index 417417f439..89d33f98d2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/DefaultStateService.kt @@ -21,16 +21,20 @@ import androidx.lifecycle.LiveData import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject +import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toContent +import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.GuestAccess import org.matrix.android.sdk.api.session.room.model.RoomCanonicalAliasContent import org.matrix.android.sdk.api.session.room.model.RoomHistoryVisibility import org.matrix.android.sdk.api.session.room.model.RoomJoinRules import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesAllowEntry import org.matrix.android.sdk.api.session.room.model.RoomJoinRulesContent +import org.matrix.android.sdk.api.session.room.model.livelocation.BeaconInfo +import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationBeaconContent import org.matrix.android.sdk.api.session.room.state.StateService import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.api.util.MimeTypes @@ -186,4 +190,42 @@ internal class DefaultStateService @AssistedInject constructor(@Assisted private } updateJoinRule(RoomJoinRules.RESTRICTED, null, allowEntries) } + + override suspend fun stopLiveLocation(userId: String) { + getLiveLocationBeaconInfo(userId, true)?.let { beaconInfoStateEvent -> + beaconInfoStateEvent.getClearContent()?.toModel<LiveLocationBeaconContent>()?.let { content -> + val beaconContent = LiveLocationBeaconContent( + unstableBeaconInfo = BeaconInfo( + description = content.getBestBeaconInfo()?.description, + timeout = content.getBestBeaconInfo()?.timeout, + isLive = false, + ), + unstableTimestampAsMilliseconds = System.currentTimeMillis() + ).toContent() + + beaconInfoStateEvent.stateKey?.let { + sendStateEvent( + eventType = EventType.STATE_ROOM_BEACON_INFO.first(), + body = beaconContent, + stateKey = it + ) + } + } + } + } + + override suspend fun getLiveLocationBeaconInfo(userId: String, filterOnlyLive: Boolean): Event? { + return EventType.STATE_ROOM_BEACON_INFO + .mapNotNull { + stateEventDataSource.getStateEvent( + roomId = roomId, + eventType = it, + stateKey = QueryStringValue.Equals(userId) + ) + } + .firstOrNull { beaconInfoEvent -> + !filterOnlyLive || + beaconInfoEvent.getClearContent()?.toModel<LiveLocationBeaconContent>()?.getBestBeaconInfo()?.isLive.orFalse() + } + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt index 2114b9c590..42d6677409 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/state/StateEventDataSource.kt @@ -32,7 +32,6 @@ import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntityFields import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.query.QueryStringValueProcessor -import org.matrix.android.sdk.internal.query.process import javax.inject.Inject internal class StateEventDataSource @Inject constructor( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/GraphUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/GraphUtils.kt index b7e6548b54..e3a215445d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/GraphUtils.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/GraphUtils.kt @@ -18,16 +18,16 @@ package org.matrix.android.sdk.internal.session.room.summary import java.util.LinkedList -data class GraphNode( +internal data class GraphNode( val name: String ) -data class GraphEdge( +internal data class GraphEdge( val source: GraphNode, val destination: GraphNode ) -class Graph { +internal class Graph { private val adjacencyList: HashMap<GraphNode, ArrayList<GraphEdge>> = HashMap() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt index 2920bba7c8..c60d2cbb40 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/summary/RoomSummaryUpdater.kt @@ -23,6 +23,7 @@ import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataTypes import org.matrix.android.sdk.api.session.room.model.Membership @@ -41,7 +42,6 @@ import org.matrix.android.sdk.api.session.sync.model.RoomSyncSummary import org.matrix.android.sdk.api.session.sync.model.RoomSyncUnreadNotifications import org.matrix.android.sdk.internal.crypto.EventDecryptor import org.matrix.android.sdk.internal.crypto.crosssigning.DefaultCrossSigningService -import org.matrix.android.sdk.internal.crypto.model.event.EncryptionEventContent import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.database.model.CurrentStateEventEntity diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt index 000a500c61..b7527f16bc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimeline.kt @@ -38,7 +38,7 @@ import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.room.timeline.Timeline import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings -import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask import org.matrix.android.sdk.internal.session.room.relation.threads.FetchThreadTimelineTask diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt index 1ba2aff191..826c9d7c48 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/DefaultTimelineService.kt @@ -26,8 +26,8 @@ import org.matrix.android.sdk.api.session.room.timeline.Timeline import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.TimelineService import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.api.util.Optional -import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.room.membership.LoadRoomMembersTask diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetEventTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetEventTask.kt index 9ede2f6562..5bca5118b8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetEventTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/GetEventTask.kt @@ -17,9 +17,9 @@ package org.matrix.android.sdk.internal.session.room.timeline import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.internal.crypto.EventDecryptor -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.network.GlobalErrorReceiver import org.matrix.android.sdk.internal.network.executeRequest import org.matrix.android.sdk.internal.session.room.RoomAPI diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt index 1ab829417c..a2056b9afd 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/LoadTimelineStrategy.kt @@ -31,8 +31,8 @@ import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.room.timeline.Timeline import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.internal.database.helper.addIfNecessary -import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper import org.matrix.android.sdk.internal.database.model.ChunkEntity import org.matrix.android.sdk.internal.database.model.ChunkEntityFields diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt index 21c7f04839..a9bf2af793 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineChunk.kt @@ -32,7 +32,7 @@ import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.room.timeline.Timeline import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.TimelineSettings -import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.internal.database.mapper.EventMapper import org.matrix.android.sdk.internal.database.mapper.TimelineEventMapper import org.matrix.android.sdk.internal.database.model.ChunkEntity diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt index 3ddd877b78..5c30dc20d9 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TimelineEventDecryptor.kt @@ -20,11 +20,10 @@ import io.realm.RealmConfiguration import kotlinx.coroutines.runBlocking import org.matrix.android.sdk.api.session.crypto.CryptoService import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.NewSessionListener import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.internal.crypto.NewSessionListener -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent -import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.database.model.EventEntity import org.matrix.android.sdk.internal.database.query.where @@ -40,7 +39,6 @@ internal class TimelineEventDecryptor @Inject constructor( private val realmConfiguration: RealmConfiguration, private val cryptoService: CryptoService, private val threadsAwarenessHandler: ThreadsAwarenessHandler, - private val lightweightSettingsStorage: LightweightSettingsStorage ) { private val newSessionListener = object : NewSessionListener { @@ -113,15 +111,16 @@ internal class TimelineEventDecryptor @Inject constructor( private fun threadAwareNonEncryptedEvents(request: DecryptionRequest, realm: Realm) { val event = request.event - realm.executeTransaction { - val eventId = event.eventId ?: return@executeTransaction - val eventEntity = EventEntity - .where(it, eventId = eventId) - .findFirst() - val decryptedEvent = eventEntity?.asDomain() - threadsAwarenessHandler.makeEventThreadAware(realm, event.roomId, decryptedEvent, eventEntity) + realm.executeTransaction { + val eventId = event.eventId ?: return@executeTransaction + val eventEntity = EventEntity + .where(it, eventId = eventId) + .findFirst() + val decryptedEvent = eventEntity?.asDomain() + threadsAwarenessHandler.makeEventThreadAware(realm, event.roomId, decryptedEvent, eventEntity) } } + private suspend fun processDecryptRequest(request: DecryptionRequest, realm: Realm) { val event = request.event val timelineId = request.timelineId diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt index ff4b6c69f9..14908ea453 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/timeline/TokenChunkEventPersistor.kt @@ -23,13 +23,13 @@ import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.send.SendState +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.internal.database.helper.addIfNecessary import org.matrix.android.sdk.internal.database.helper.addStateEvent import org.matrix.android.sdk.internal.database.helper.addTimelineEvent import org.matrix.android.sdk.internal.database.helper.doesNextChunksVerifyCondition import org.matrix.android.sdk.internal.database.helper.doesPrevChunksVerifyCondition import org.matrix.android.sdk.internal.database.helper.updateThreadSummaryIfNeeded -import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage import org.matrix.android.sdk.internal.database.mapper.toEntity import org.matrix.android.sdk.internal.database.model.ChunkEntity import org.matrix.android.sdk.internal.database.model.EventEntity @@ -86,25 +86,7 @@ internal class TokenChunkEventPersistor @Inject constructor( val existingChunk = ChunkEntity.find(realm, roomId, prevToken = prevToken, nextToken = nextToken) if (existingChunk != null) { Timber.v("This chunk is already in the db, checking if this might be caused by broken links") - if (direction == PaginationDirection.FORWARDS) { - val prevChunks = ChunkEntity.findAll(realm, roomId, nextToken = prevToken) - Timber.v("Found ${prevChunks?.size} prevChunks") - prevChunks?.forEach { - if (it.nextChunk != existingChunk) { - Timber.i("Set nextChunk for ${it.identifier()} from ${it.nextChunk?.identifier()} to ${existingChunk.identifier()}") - it.nextChunk = existingChunk - } - } - } else { - val nextChunks = ChunkEntity.findAll(realm, roomId, prevToken = nextToken) - Timber.v("Found ${nextChunks?.size} nextChunks") - nextChunks?.forEach { - if (it.prevChunk != existingChunk) { - Timber.i("Set prevChunk for ${it.identifier()} from ${it.prevChunk?.identifier()} to ${existingChunk.identifier()}") - it.prevChunk = existingChunk - } - } - } + existingChunk.fixChunkLinks(realm, roomId, direction, prevToken, nextToken) return@awaitTransaction } val prevChunk = ChunkEntity.find(realm, roomId, nextToken = prevToken) @@ -139,6 +121,34 @@ internal class TokenChunkEventPersistor @Inject constructor( } } + private fun ChunkEntity.fixChunkLinks( + realm: Realm, + roomId: String, + direction: PaginationDirection, + prevToken: String?, + nextToken: String?, + ) { + if (direction == PaginationDirection.FORWARDS) { + val prevChunks = ChunkEntity.findAll(realm, roomId, nextToken = prevToken) + Timber.v("Found ${prevChunks?.size} prevChunks") + prevChunks?.forEach { + if (it.nextChunk != this) { + Timber.i("Set nextChunk for ${it.identifier()} from ${it.nextChunk?.identifier()} to ${identifier()}") + it.nextChunk = this + } + } + } else { + val nextChunks = ChunkEntity.findAll(realm, roomId, prevToken = nextToken) + Timber.v("Found ${nextChunks?.size} nextChunks") + nextChunks?.forEach { + if (it.prevChunk != this) { + Timber.i("Set prevChunk for ${it.identifier()} from ${it.prevChunk?.identifier()} to ${identifier()}") + it.prevChunk = this + } + } + } + } + private fun handleReachEnd(roomId: String, direction: PaginationDirection, currentChunk: ChunkEntity) { Timber.v("Reach end of $roomId") if (direction == PaginationDirection.FORWARDS) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/TypingBody.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/TypingBody.kt index 973870bb47..66913e0cbf 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/TypingBody.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/TypingBody.kt @@ -20,7 +20,7 @@ import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -data class TypingBody( +internal data class TypingBody( // Required. Whether the user is typing or not. If false, the timeout key can be omitted. @Json(name = "typing") val typing: Boolean, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/TypingEventContent.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/TypingEventContent.kt index 488d38d762..5b01085648 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/TypingEventContent.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/typing/TypingEventContent.kt @@ -20,7 +20,7 @@ import com.squareup.moshi.Json import com.squareup.moshi.JsonClass @JsonClass(generateAdapter = true) -data class TypingEventContent( +internal data class TypingEventContent( @Json(name = "user_ids") val typingUserIds: List<String> = emptyList() ) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/uploads/GetUploadsTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/uploads/GetUploadsTask.kt index 028c3e9193..7daf506c14 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/uploads/GetUploadsTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/uploads/GetUploadsTask.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.room.uploads import com.zhuinden.monarchy.Monarchy +import io.realm.Sort import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel @@ -75,6 +76,7 @@ internal class DefaultGetUploadsTask @Inject constructor( monarchy.doWithRealm { realm -> eventsFromRealm = EventEntity.whereType(realm, EventType.ENCRYPTED, params.roomId) .like(EventEntityFields.DECRYPTION_RESULT_JSON, TimelineEventFilter.DecryptedContent.URL) + .sort(EventEntityFields.ORIGIN_SERVER_TS, Sort.DESCENDING) .findAll() .map { it.asDomain() } // Exclude stickers diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtils.kt index fad1840e51..17dc90fdb0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtils.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/securestorage/SecretStoringUtils.kt @@ -34,7 +34,6 @@ import java.io.InputStream import java.io.ObjectInputStream import java.io.ObjectOutputStream import java.io.OutputStream -import java.lang.IllegalArgumentException import java.math.BigInteger import java.security.KeyPairGenerator import java.security.KeyStore diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt index e764ab551a..05cff7dd89 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/DefaultSpaceService.kt @@ -43,6 +43,7 @@ import org.matrix.android.sdk.api.session.space.SpaceService import org.matrix.android.sdk.api.session.space.SpaceSummaryQueryParams import org.matrix.android.sdk.api.session.space.model.SpaceChildContent import org.matrix.android.sdk.api.session.space.model.SpaceParentContent +import org.matrix.android.sdk.api.session.space.peeking.SpacePeekResult import org.matrix.android.sdk.internal.di.UserId import org.matrix.android.sdk.internal.session.room.RoomGetter import org.matrix.android.sdk.internal.session.room.SpaceGetter @@ -51,7 +52,6 @@ import org.matrix.android.sdk.internal.session.room.membership.leaving.LeaveRoom import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryDataSource import org.matrix.android.sdk.internal.session.space.peeking.PeekSpaceTask -import org.matrix.android.sdk.internal.session.space.peeking.SpacePeekResult import javax.inject.Inject internal class DefaultSpaceService @Inject constructor( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/PeekSpaceTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/PeekSpaceTask.kt index c45d4420ae..3647941998 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/PeekSpaceTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/space/peeking/PeekSpaceTask.kt @@ -23,6 +23,11 @@ import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent import org.matrix.android.sdk.api.session.room.peeking.PeekResult import org.matrix.android.sdk.api.session.space.model.SpaceChildContent +import org.matrix.android.sdk.api.session.space.peeking.ISpaceChild +import org.matrix.android.sdk.api.session.space.peeking.SpaceChildPeekResult +import org.matrix.android.sdk.api.session.space.peeking.SpacePeekResult +import org.matrix.android.sdk.api.session.space.peeking.SpacePeekSummary +import org.matrix.android.sdk.api.session.space.peeking.SpaceSubChildPeekResult import org.matrix.android.sdk.internal.session.room.peeking.PeekRoomTask import org.matrix.android.sdk.internal.session.room.peeking.ResolveRoomStateTask import org.matrix.android.sdk.internal.task.Task diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncEphemeralTemporaryStore.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncEphemeralTemporaryStore.kt index 8c68e224dc..ef9f468c86 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncEphemeralTemporaryStore.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/RoomSyncEphemeralTemporaryStore.kt @@ -21,8 +21,8 @@ import com.squareup.moshi.Moshi import okio.buffer import okio.source import org.matrix.android.sdk.api.session.sync.model.RoomSyncEphemeral +import org.matrix.android.sdk.api.util.md5 import org.matrix.android.sdk.internal.di.SessionFilesDirectory -import org.matrix.android.sdk.internal.util.md5 import timber.log.Timber import java.io.File import javax.inject.Inject diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncPresence.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncPresence.kt index 18e17c7d13..4f1fe43b7d 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncPresence.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncPresence.kt @@ -16,6 +16,8 @@ package org.matrix.android.sdk.internal.session.sync +import org.matrix.android.sdk.api.session.presence.model.PresenceEnum + /** * For `set_presence` parameter in the /sync request * @@ -24,8 +26,19 @@ package org.matrix.android.sdk.internal.session.sync * parameter is set to "offline" then the client is not marked as being online when it uses this API. * When set to "unavailable", the client is marked as being idle. One of: ["offline", "online", "unavailable"] */ -enum class SyncPresence(val value: String) { +internal enum class SyncPresence(val value: String) { Offline("offline"), Online("online"), - Unavailable("unavailable") + Unavailable("unavailable"); + + companion object { + fun from(presenceEnum: PresenceEnum): SyncPresence { + return when (presenceEnum) { + PresenceEnum.ONLINE -> Online + PresenceEnum.OFFLINE -> Offline + PresenceEnum.UNAVAILABLE -> Unavailable + } + } + fun from(s: String?): SyncPresence? = values().find { it.value == s } + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt index 1bbf54a788..97850e81d3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponseHandler.kt @@ -26,7 +26,6 @@ import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.SessionManager import org.matrix.android.sdk.internal.crypto.DefaultCryptoService -import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.di.SessionId import org.matrix.android.sdk.internal.di.WorkManagerProvider @@ -42,7 +41,6 @@ import org.matrix.android.sdk.internal.session.sync.handler.PresenceSyncHandler import org.matrix.android.sdk.internal.session.sync.handler.SyncResponsePostTreatmentAggregatorHandler import org.matrix.android.sdk.internal.session.sync.handler.UserAccountDataSyncHandler import org.matrix.android.sdk.internal.session.sync.handler.room.RoomSyncHandler -import org.matrix.android.sdk.internal.session.sync.handler.room.ThreadsAwarenessHandler import org.matrix.android.sdk.internal.util.awaitTransaction import org.matrix.android.sdk.internal.worker.WorkerParamsFactory import timber.log.Timber @@ -65,10 +63,8 @@ internal class SyncResponseHandler @Inject constructor( private val aggregatorHandler: SyncResponsePostTreatmentAggregatorHandler, private val cryptoService: DefaultCryptoService, private val tokenStore: SyncTokenStore, - private val lightweightSettingsStorage: LightweightSettingsStorage, private val processEventForPushTask: ProcessEventForPushTask, private val pushRuleService: PushRuleService, - private val threadsAwarenessHandler: ThreadsAwarenessHandler, private val presenceSyncHandler: PresenceSyncHandler ) { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt index fe44531390..e9452c59fc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncResponsePostTreatmentAggregator.kt @@ -22,4 +22,7 @@ internal class SyncResponsePostTreatmentAggregator { // Map of roomId to directUserId val directChatsToCheck = mutableMapOf<String, String>() + + // List of userIds to fetch and update at the end of incremental syncs + val userIdsToFetch = mutableListOf<String>() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt index bcb0d54e8e..98e07afab8 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/SyncTask.kt @@ -24,6 +24,8 @@ import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.initsync.InitSyncStep import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.statistics.StatisticEvent +import org.matrix.android.sdk.api.session.sync.InitialSyncStrategy +import org.matrix.android.sdk.api.session.sync.initialSyncStrategy import org.matrix.android.sdk.api.session.sync.model.LazyRoomSyncEphemeral import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.di.SessionFilesDirectory diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt index 9ae7b82777..429f498533 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/CryptoSyncHandler.kt @@ -18,16 +18,16 @@ package org.matrix.android.sdk.internal.session.sync.handler import org.matrix.android.sdk.api.logger.LoggerTag import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.MXEventDecryptionResult +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.OlmEventContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.api.session.sync.model.ToDeviceSyncResponse import org.matrix.android.sdk.internal.crypto.DefaultCryptoService -import org.matrix.android.sdk.internal.crypto.MXEventDecryptionResult -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult -import org.matrix.android.sdk.internal.crypto.model.event.OlmEventContent import org.matrix.android.sdk.internal.crypto.verification.DefaultVerificationService import org.matrix.android.sdk.internal.session.initsync.ProgressReporter import timber.log.Timber diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/PresenceSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/PresenceSyncHandler.kt index e5bed12181..6a7af1dda4 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/PresenceSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/PresenceSyncHandler.kt @@ -31,26 +31,24 @@ import javax.inject.Inject internal class PresenceSyncHandler @Inject constructor(private val matrixConfiguration: MatrixConfiguration) { fun handle(realm: Realm, presenceSyncResponse: PresenceSyncResponse?) { - if (matrixConfiguration.presenceSyncEnabled) { - presenceSyncResponse?.events - ?.filter { event -> event.type == EventType.PRESENCE } - ?.forEach { event -> - val content = event.getPresenceContent() ?: return@forEach - val userId = event.senderId ?: return@forEach - val userPresenceEntity = UserPresenceEntity( - userId = userId, - lastActiveAgo = content.lastActiveAgo, - statusMessage = content.statusMessage, - isCurrentlyActive = content.isCurrentlyActive, - avatarUrl = content.avatarUrl, - displayName = content.displayName - ).also { - it.presence = content.presence - } - - storePresenceToDB(realm, userPresenceEntity) + presenceSyncResponse?.events + ?.filter { event -> event.type == EventType.PRESENCE } + ?.forEach { event -> + val content = event.getPresenceContent() ?: return@forEach + val userId = event.senderId ?: return@forEach + val userPresenceEntity = UserPresenceEntity( + userId = userId, + lastActiveAgo = content.lastActiveAgo, + statusMessage = content.statusMessage, + isCurrentlyActive = content.isCurrentlyActive, + avatarUrl = content.avatarUrl, + displayName = content.displayName + ).also { + it.presence = content.presence } - } + + storePresenceToDB(realm, userPresenceEntity) + } } /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt index 1e0e87a450..c638ed4f80 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/SyncResponsePostTreatmentAggregatorHandler.kt @@ -16,22 +16,32 @@ package org.matrix.android.sdk.internal.session.sync.handler +import com.zhuinden.monarchy.Monarchy import org.matrix.android.sdk.api.MatrixPatterns +import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.session.user.model.User +import org.matrix.android.sdk.internal.di.SessionDatabase +import org.matrix.android.sdk.internal.session.profile.GetProfileInfoTask import org.matrix.android.sdk.internal.session.sync.RoomSyncEphemeralTemporaryStore import org.matrix.android.sdk.internal.session.sync.SyncResponsePostTreatmentAggregator import org.matrix.android.sdk.internal.session.sync.model.accountdata.toMutable +import org.matrix.android.sdk.internal.session.user.UserEntityFactory import org.matrix.android.sdk.internal.session.user.accountdata.DirectChatsHelper import org.matrix.android.sdk.internal.session.user.accountdata.UpdateUserAccountDataTask +import org.matrix.android.sdk.internal.util.awaitTransaction import javax.inject.Inject internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( private val directChatsHelper: DirectChatsHelper, private val ephemeralTemporaryStore: RoomSyncEphemeralTemporaryStore, - private val updateUserAccountDataTask: UpdateUserAccountDataTask + private val updateUserAccountDataTask: UpdateUserAccountDataTask, + private val getProfileInfoTask: GetProfileInfoTask, + @SessionDatabase private val monarchy: Monarchy, ) { - suspend fun handle(synResHaResponsePostTreatmentAggregator: SyncResponsePostTreatmentAggregator) { - cleanupEphemeralFiles(synResHaResponsePostTreatmentAggregator.ephemeralFilesToDelete) - updateDirectUserIds(synResHaResponsePostTreatmentAggregator.directChatsToCheck) + suspend fun handle(aggregator: SyncResponsePostTreatmentAggregator) { + cleanupEphemeralFiles(aggregator.ephemeralFilesToDelete) + updateDirectUserIds(aggregator.directChatsToCheck) + fetchAndUpdateUsers(aggregator.userIdsToFetch) } private fun cleanupEphemeralFiles(ephemeralFilesToDelete: List<String>) { @@ -59,13 +69,33 @@ internal class SyncResponsePostTreatmentAggregatorHandler @Inject constructor( } // remove roomId from currentDirectUserId entry - hasUpdate = hasUpdate or(directChats[currentDirectUserId]?.remove(roomId) == true) + hasUpdate = hasUpdate or (directChats[currentDirectUserId]?.remove(roomId) == true) // remove currentDirectUserId entry if there is no attached room anymore - hasUpdate = hasUpdate or(directChats.takeIf { it[currentDirectUserId].isNullOrEmpty() }?.remove(currentDirectUserId) != null) + hasUpdate = hasUpdate or (directChats.takeIf { it[currentDirectUserId].isNullOrEmpty() }?.remove(currentDirectUserId) != null) } } if (hasUpdate) { updateUserAccountDataTask.execute(UpdateUserAccountDataTask.DirectChatParams(directMessages = directChats)) } } + + private suspend fun fetchAndUpdateUsers(userIdsToFetch: List<String>) { + fetchUsers(userIdsToFetch) + .takeIf { it.isNotEmpty() } + ?.saveLocally() + } + + private suspend fun fetchUsers(userIdsToFetch: List<String>) = userIdsToFetch.mapNotNull { + tryOrNull { + val profileJson = getProfileInfoTask.execute(GetProfileInfoTask.Params(it)) + User.fromJson(it, profileJson) + } + } + + private suspend fun List<User>.saveLocally() { + val userEntities = map { user -> UserEntityFactory.create(user) } + monarchy.awaitTransaction { + it.insertOrUpdate(userEntities) + } + } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ReadReceiptHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ReadReceiptHandler.kt index 025ee329f8..2c84f1e692 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ReadReceiptHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ReadReceiptHandler.kt @@ -33,7 +33,7 @@ import javax.inject.Inject // value : dict key $UserId // value dict key ts // dict value ts value -typealias ReadReceiptContent = Map<String, Map<String, Map<String, Map<String, Double>>>> +internal typealias ReadReceiptContent = Map<String, Map<String, Map<String, Map<String, Double>>>> private const val READ_KEY = "m.read" private const val TIMESTAMP_KEY = "ts" diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt index 2991dc25db..6cbf13aee0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/RoomSyncHandler.kt @@ -20,7 +20,9 @@ import dagger.Lazy import io.realm.Realm import io.realm.kotlin.createObject import kotlinx.coroutines.runBlocking +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel @@ -30,18 +32,18 @@ import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomMemberContent import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.room.threads.model.ThreadSummaryUpdateType +import org.matrix.android.sdk.api.session.sync.InitialSyncStrategy +import org.matrix.android.sdk.api.session.sync.initialSyncStrategy import org.matrix.android.sdk.api.session.sync.model.InvitedRoomSync import org.matrix.android.sdk.api.session.sync.model.LazyRoomSyncEphemeral import org.matrix.android.sdk.api.session.sync.model.RoomSync import org.matrix.android.sdk.api.session.sync.model.RoomsSyncResponse +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.internal.crypto.DefaultCryptoService -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import org.matrix.android.sdk.internal.database.helper.addIfNecessary import org.matrix.android.sdk.internal.database.helper.addTimelineEvent import org.matrix.android.sdk.internal.database.helper.createOrUpdate import org.matrix.android.sdk.internal.database.helper.updateThreadSummaryIfNeeded -import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage import org.matrix.android.sdk.internal.database.mapper.asDomain import org.matrix.android.sdk.internal.database.mapper.toEntity import org.matrix.android.sdk.internal.database.model.ChunkEntity @@ -74,9 +76,7 @@ import org.matrix.android.sdk.internal.session.room.summary.RoomSummaryUpdater import org.matrix.android.sdk.internal.session.room.timeline.PaginationDirection import org.matrix.android.sdk.internal.session.room.timeline.TimelineInput import org.matrix.android.sdk.internal.session.room.typing.TypingEventContent -import org.matrix.android.sdk.internal.session.sync.InitialSyncStrategy import org.matrix.android.sdk.internal.session.sync.SyncResponsePostTreatmentAggregator -import org.matrix.android.sdk.internal.session.sync.initialSyncStrategy import org.matrix.android.sdk.internal.session.sync.parsing.RoomSyncAccountDataHandler import org.matrix.android.sdk.internal.util.computeBestChunkSize import timber.log.Timber @@ -107,7 +107,6 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle isInitialSync: Boolean, aggregator: SyncResponsePostTreatmentAggregator, reporter: ProgressReporter? = null) { - Timber.v("Execute transaction from $this") handleRoomSync(realm, HandlingStrategy.JOINED(roomsSyncResponse.join), isInitialSync, aggregator, reporter) handleRoomSync(realm, HandlingStrategy.INVITED(roomsSyncResponse.invite), isInitialSync, aggregator, reporter) handleRoomSync(realm, HandlingStrategy.LEFT(roomsSyncResponse.leave), isInitialSync, aggregator, reporter) @@ -207,6 +206,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle syncLocalTimestampMillis: Long, aggregator: SyncResponsePostTreatmentAggregator): RoomEntity { Timber.v("Handle join sync for room $roomId") + val isInitialSync = insertType == EventInsertType.INITIAL_SYNC val ephemeralResult = (roomSync.ephemeral as? LazyRoomSyncEphemeral.Parsed) ?._roomSyncEphemeral @@ -241,7 +241,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle } // Give info to crypto module cryptoService.onStateEvent(roomId, event) - roomMemberEventHandler.handle(realm, roomId, event, aggregator) + roomMemberEventHandler.handle(realm, roomId, event, isInitialSync, aggregator) } } if (roomSync.timeline?.events?.isNotEmpty() == true) { @@ -284,6 +284,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle insertType: EventInsertType, syncLocalTimestampMillis: Long): RoomEntity { Timber.v("Handle invited sync for room $roomId") + val isInitialSync = insertType == EventInsertType.INITIAL_SYNC val roomEntity = RoomEntity.getOrCreate(realm, roomId) roomEntity.membership = Membership.INVITE if (roomSync.inviteState != null && roomSync.inviteState.events.isNotEmpty()) { @@ -297,7 +298,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle eventId = eventEntity.eventId root = eventEntity } - roomMemberEventHandler.handle(realm, roomId, event) + roomMemberEventHandler.handle(realm, roomId, event, isInitialSync) } } val inviterEvent = roomSync.inviteState?.events?.lastOrNull { @@ -313,6 +314,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle roomSync: RoomSync, insertType: EventInsertType, syncLocalTimestampMillis: Long): RoomEntity { + val isInitialSync = insertType == EventInsertType.INITIAL_SYNC val roomEntity = RoomEntity.getOrCreate(realm, roomId) for (event in roomSync.state?.events.orEmpty()) { if (event.eventId == null || event.stateKey == null || event.type == null) { @@ -324,7 +326,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle eventId = event.eventId root = eventEntity } - roomMemberEventHandler.handle(realm, roomId, event) + roomMemberEventHandler.handle(realm, roomId, event, isInitialSync) } for (event in roomSync.timeline?.events.orEmpty()) { if (event.eventId == null || event.senderId == null || event.type == null) { @@ -338,7 +340,7 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle root = eventEntity } if (event.type == EventType.STATE_ROOM_MEMBER) { - roomMemberEventHandler.handle(realm, roomEntity.roomId, event) + roomMemberEventHandler.handle(realm, roomEntity.roomId, event, isInitialSync) } } } @@ -382,11 +384,11 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle continue } - eventIds.add(event.eventId) - liveEventService.get().dispatchLiveEventReceived(event, roomId, insertType == EventInsertType.INITIAL_SYNC) - val isInitialSync = insertType == EventInsertType.INITIAL_SYNC + eventIds.add(event.eventId) + liveEventService.get().dispatchLiveEventReceived(event, roomId, isInitialSync) + if (event.isEncrypted() && !isInitialSync) { runBlocking { decryptIfNeeded(event, roomId) @@ -405,9 +407,8 @@ internal class RoomSyncHandler @Inject constructor(private val readReceiptHandle root = eventEntity } if (event.type == EventType.STATE_ROOM_MEMBER) { - val fixedContent = event.getFixedRoomMemberContent() - roomMemberContentsByUser[event.stateKey] = fixedContent - roomMemberEventHandler.handle(realm, roomEntity.roomId, event.stateKey, fixedContent, aggregator) + roomMemberContentsByUser[event.stateKey] = event.getFixedRoomMemberContent() + roomMemberEventHandler.handle(realm, roomEntity.roomId, event, isInitialSync, aggregator) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt index db9799d51e..efc8e39a18 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/handler/room/ThreadsAwarenessHandler.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.internal.session.sync.handler.room import com.zhuinden.monarchy.Monarchy import io.realm.Realm import io.realm.kotlin.where +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType @@ -35,9 +36,8 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageType import org.matrix.android.sdk.api.session.room.model.relation.RelationDefaultContent import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.sync.model.SyncResponse +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult -import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage import org.matrix.android.sdk.internal.database.mapper.ContentMapper import org.matrix.android.sdk.internal.database.mapper.EventMapper import org.matrix.android.sdk.internal.database.mapper.asDomain diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt index d93f350377..f3474b44de 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/job/SyncThread.kt @@ -39,8 +39,8 @@ import org.matrix.android.sdk.api.session.sync.SyncState import org.matrix.android.sdk.api.session.sync.model.SyncResponse import org.matrix.android.sdk.internal.network.NetworkConnectivityChecker import org.matrix.android.sdk.internal.session.call.ActiveCallHandler -import org.matrix.android.sdk.internal.session.sync.SyncPresence import org.matrix.android.sdk.internal.session.sync.SyncTask +import org.matrix.android.sdk.internal.settings.DefaultLightweightSettingsStorage import org.matrix.android.sdk.internal.util.BackgroundDetectionObserver import org.matrix.android.sdk.internal.util.Debouncer import org.matrix.android.sdk.internal.util.createUIHandler @@ -59,7 +59,8 @@ private val loggerTag = LoggerTag("SyncThread", LoggerTag.SYNC) internal class SyncThread @Inject constructor(private val syncTask: SyncTask, private val networkConnectivityChecker: NetworkConnectivityChecker, private val backgroundDetectionObserver: BackgroundDetectionObserver, - private val activeCallHandler: ActiveCallHandler + private val activeCallHandler: ActiveCallHandler, + private val lightweightSettingsStorage: DefaultLightweightSettingsStorage ) : Thread("SyncThread"), NetworkConnectivityChecker.Listener, BackgroundDetectionObserver.Listener { private var state: SyncState = SyncState.Idle @@ -104,10 +105,12 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask, fun pause() = synchronized(lock) { if (isStarted) { - Timber.tag(loggerTag.value).i("Pause sync...") + Timber.tag(loggerTag.value).i("Pause sync... Not cancelling incremental sync") isStarted = false retryNoNetworkTask?.cancel() - syncScope.coroutineContext.cancelChildren() + // Do not cancel the current incremental sync. + // Incremental sync can be long and it requires the user to wait for the treatment to end, + // else all is restarted from the beginning each time the user moves the app to foreground. } } @@ -180,7 +183,8 @@ internal class SyncThread @Inject constructor(private val syncTask: SyncTask, else -> DEFAULT_LONG_POOL_TIMEOUT } Timber.tag(loggerTag.value).i("Execute sync request with timeout $timeout") - val params = SyncTask.Params(timeout, SyncPresence.Online, afterPause = afterPause) + val presence = lightweightSettingsStorage.getSyncPresenceStatus() + val params = SyncTask.Params(timeout, presence, afterPause = afterPause) val sync = syncScope.launch { previousSyncResponseHasToDevice = doSync(params) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt index 012470a076..c83f658bfe 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/DefaultLazyRoomSyncEphemeralJsonAdapter.kt @@ -21,9 +21,9 @@ import com.squareup.moshi.JsonAdapter import com.squareup.moshi.JsonReader import com.squareup.moshi.JsonWriter import com.squareup.moshi.ToJson +import org.matrix.android.sdk.api.session.sync.InitialSyncStrategy import org.matrix.android.sdk.api.session.sync.model.LazyRoomSyncEphemeral import org.matrix.android.sdk.api.session.sync.model.RoomSyncEphemeral -import org.matrix.android.sdk.internal.session.sync.InitialSyncStrategy import org.matrix.android.sdk.internal.session.sync.RoomSyncEphemeralTemporaryStore import timber.log.Timber diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt index f00cce2d5e..de3269ca1e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/sync/parsing/InitialSyncResponseParser.kt @@ -19,8 +19,8 @@ package org.matrix.android.sdk.internal.session.sync.parsing import com.squareup.moshi.Moshi import okio.buffer import okio.source +import org.matrix.android.sdk.api.session.sync.InitialSyncStrategy import org.matrix.android.sdk.api.session.sync.model.SyncResponse -import org.matrix.android.sdk.internal.session.sync.InitialSyncStrategy import org.matrix.android.sdk.internal.session.sync.RoomSyncEphemeralTemporaryStore import timber.log.Timber import java.io.File diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt index 6205e3e4b1..5f62f40ab3 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/DefaultTermsService.kt @@ -23,6 +23,7 @@ import org.matrix.android.sdk.api.failure.toRegistrationFlowResponse import org.matrix.android.sdk.api.session.accountdata.UserAccountDataTypes import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.terms.GetTermsResponse +import org.matrix.android.sdk.api.session.terms.TermsResponse import org.matrix.android.sdk.api.session.terms.TermsService import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.di.UnauthenticatedWithCertificate diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsAPI.kt index fb6aff5a9e..1f117de67e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/terms/TermsAPI.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.internal.session.terms +import org.matrix.android.sdk.api.session.terms.TermsResponse import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.api.util.emptyJsonDict import org.matrix.android.sdk.internal.network.HttpHeaders diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/DefaultUserService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/DefaultUserService.kt index 52b8cc3689..4ffc42e714 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/DefaultUserService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/DefaultUserService.kt @@ -18,7 +18,6 @@ package org.matrix.android.sdk.internal.session.user import androidx.lifecycle.LiveData import androidx.paging.PagedList -import org.matrix.android.sdk.api.session.profile.ProfileService import org.matrix.android.sdk.api.session.user.UserService import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.api.util.Optional @@ -37,16 +36,10 @@ internal class DefaultUserService @Inject constructor(private val userDataSource } override suspend fun resolveUser(userId: String): User { - val known = getUser(userId) - if (known != null) { - return known - } else { + return getUser(userId) ?: run { val params = GetProfileInfoTask.Params(userId) - val data = getProfileInfoTask.execute(params) - return User( - userId, - data[ProfileService.DISPLAY_NAME_KEY] as? String, - data[ProfileService.AVATAR_URL_KEY] as? String) + val json = getProfileInfoTask.execute(params) + User.fromJson(userId, json) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/UserEntityFactory.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/UserEntityFactory.kt index 9a9458e84b..46ea7547b0 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/UserEntityFactory.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/UserEntityFactory.kt @@ -17,6 +17,7 @@ package org.matrix.android.sdk.internal.session.user import org.matrix.android.sdk.api.session.room.model.RoomMemberContent +import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.internal.database.model.UserEntity internal object UserEntityFactory { @@ -24,8 +25,16 @@ internal object UserEntityFactory { fun create(userId: String, roomMember: RoomMemberContent): UserEntity { return UserEntity( userId = userId, - displayName = roomMember.displayName ?: "", - avatarUrl = roomMember.avatarUrl ?: "" + displayName = roomMember.displayName.orEmpty(), + avatarUrl = roomMember.avatarUrl.orEmpty() + ) + } + + fun create(user: User): UserEntity { + return UserEntity( + userId = user.userId, + displayName = user.displayName.orEmpty(), + avatarUrl = user.avatarUrl.orEmpty() ) } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/AccountDataAPI.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/AccountDataAPI.kt index a759eedd18..50bf1997cc 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/AccountDataAPI.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/AccountDataAPI.kt @@ -21,7 +21,7 @@ import retrofit2.http.Body import retrofit2.http.PUT import retrofit2.http.Path -interface AccountDataAPI { +internal interface AccountDataAPI { /** * Set some account_data for the client. diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DefaultSessionAccountDataService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DefaultSessionAccountDataService.kt index ddcac475ee..59c4dd671e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DefaultSessionAccountDataService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/user/accountdata/DefaultSessionAccountDataService.kt @@ -23,12 +23,12 @@ import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent import org.matrix.android.sdk.api.session.events.model.Content import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataEvent import org.matrix.android.sdk.api.util.Optional +import org.matrix.android.sdk.api.util.awaitCallback import org.matrix.android.sdk.internal.di.SessionDatabase import org.matrix.android.sdk.internal.session.room.accountdata.RoomAccountDataDataSource import org.matrix.android.sdk.internal.session.sync.handler.UserAccountDataSyncHandler import org.matrix.android.sdk.internal.task.TaskExecutor import org.matrix.android.sdk.internal.task.configureWith -import org.matrix.android.sdk.internal.util.awaitCallback import javax.inject.Inject internal class DefaultSessionAccountDataService @Inject constructor( diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt index 1fa5e5f771..10b4f7f7d7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/DefaultWidgetPostAPIMediator.kt @@ -25,7 +25,6 @@ import org.matrix.android.sdk.api.util.JsonDict import org.matrix.android.sdk.internal.util.createUIHandler import timber.log.Timber import java.lang.reflect.Type -import java.util.HashMap import javax.inject.Inject internal class DefaultWidgetPostAPIMediator @Inject constructor(private val moshi: Moshi, diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt index 9f5f91d917..e18117d2d7 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/widgets/WidgetManager.kt @@ -42,7 +42,6 @@ import org.matrix.android.sdk.internal.session.room.state.StateEventDataSource import org.matrix.android.sdk.internal.session.user.accountdata.UserAccountDataDataSource import org.matrix.android.sdk.internal.session.widgets.helper.WidgetFactory import org.matrix.android.sdk.internal.session.widgets.helper.extractWidgetSequence -import java.util.HashMap import javax.inject.Inject @SessionScope diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/lightweight/LightweightSettingsStorage.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/settings/DefaultLightweightSettingsStorage.kt similarity index 51% rename from matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/lightweight/LightweightSettingsStorage.kt rename to matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/settings/DefaultLightweightSettingsStorage.kt index 069e539e2c..284d5c9910 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/lightweight/LightweightSettingsStorage.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/settings/DefaultLightweightSettingsStorage.kt @@ -1,11 +1,11 @@ /* - * Copyright 2022 The Matrix.org Foundation C.I.C. + * Copyright (c) 2022 The Matrix.org Foundation C.I.C. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -14,12 +14,14 @@ * limitations under the License. */ -package org.matrix.android.sdk.internal.database.lightweight +package org.matrix.android.sdk.internal.settings import android.content.Context import androidx.core.content.edit import androidx.preference.PreferenceManager import org.matrix.android.sdk.api.MatrixConfiguration +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage +import org.matrix.android.sdk.internal.session.sync.SyncPresence import javax.inject.Inject /** @@ -27,25 +29,46 @@ import javax.inject.Inject * on the sdk without using the database. This should be used just for sdk/user preferences and * not for large data sets */ - -class LightweightSettingsStorage @Inject constructor( +internal class DefaultLightweightSettingsStorage @Inject constructor( context: Context, private val matrixConfiguration: MatrixConfiguration -) { +) : LightweightSettingsStorage { private val sdkDefaultPrefs = PreferenceManager.getDefaultSharedPreferences(context.applicationContext) - fun setThreadMessagesEnabled(enabled: Boolean) { + override fun setThreadMessagesEnabled(enabled: Boolean) { sdkDefaultPrefs.edit { putBoolean(MATRIX_SDK_SETTINGS_THREAD_MESSAGES_ENABLED, enabled) } } - fun areThreadMessagesEnabled(): Boolean { + override fun areThreadMessagesEnabled(): Boolean { return sdkDefaultPrefs.getBoolean(MATRIX_SDK_SETTINGS_THREAD_MESSAGES_ENABLED, matrixConfiguration.threadMessagesEnabledDefault) } + /** + * Set the presence status sent on syncs when the application is in foreground. + * + * @param presence the presence status that should be sent on sync + */ + internal fun setSyncPresenceStatus(presence: SyncPresence) { + sdkDefaultPrefs.edit { + putString(MATRIX_SDK_SETTINGS_FOREGROUND_PRESENCE_STATUS, presence.value) + } + } + + /** + * Get the presence status that should be sent on syncs when the application is in foreground. + * + * @return the presence status that should be sent on sync + */ + internal fun getSyncPresenceStatus(): SyncPresence { + val presenceString = sdkDefaultPrefs.getString(MATRIX_SDK_SETTINGS_FOREGROUND_PRESENCE_STATUS, SyncPresence.Online.value) + return SyncPresence.from(presenceString) ?: SyncPresence.Online + } + companion object { const val MATRIX_SDK_SETTINGS_THREAD_MESSAGES_ENABLED = "MATRIX_SDK_SETTINGS_THREAD_MESSAGES_ENABLED" + private const val MATRIX_SDK_SETTINGS_FOREGROUND_PRESENCE_STATUS = "MATRIX_SDK_SETTINGS_FOREGROUND_PRESENCE_STATUS" } } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/settings/SettingsModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/settings/SettingsModule.kt new file mode 100644 index 0000000000..db57f69596 --- /dev/null +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/settings/SettingsModule.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2022 The Matrix.org Foundation C.I.C. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.matrix.android.sdk.internal.settings + +import dagger.Binds +import dagger.Module +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage + +@Module +internal abstract class SettingsModule { + @Binds + abstract fun bindLightweightSettingsStorage(storage: DefaultLightweightSettingsStorage): LightweightSettingsStorage +} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/BackgroundDetectionObserver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/BackgroundDetectionObserver.kt index 9c8b36a3ed..2dd16d8375 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/BackgroundDetectionObserver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/BackgroundDetectionObserver.kt @@ -20,7 +20,7 @@ import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import timber.log.Timber -interface BackgroundDetectionObserver : DefaultLifecycleObserver { +internal interface BackgroundDetectionObserver : DefaultLifecycleObserver { val isInBackground: Boolean fun register(listener: Listener) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/CompatUtil.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/CompatUtil.kt deleted file mode 100644 index 81d601f6f0..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/CompatUtil.kt +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -@file:Suppress("DEPRECATION") - -package org.matrix.android.sdk.internal.util - -import android.content.Context -import android.content.SharedPreferences -import android.os.Build -import android.preference.PreferenceManager -import android.security.KeyPairGeneratorSpec -import android.security.keystore.KeyGenParameterSpec -import android.security.keystore.KeyProperties -import android.util.Base64 -import androidx.core.content.edit -import timber.log.Timber -import java.io.IOException -import java.io.InputStream -import java.io.OutputStream -import java.math.BigInteger -import java.security.InvalidAlgorithmParameterException -import java.security.InvalidKeyException -import java.security.KeyPairGenerator -import java.security.KeyStore -import java.security.KeyStoreException -import java.security.NoSuchAlgorithmException -import java.security.NoSuchProviderException -import java.security.PrivateKey -import java.security.SecureRandom -import java.security.UnrecoverableKeyException -import java.security.cert.CertificateException -import java.security.spec.AlgorithmParameterSpec -import java.security.spec.RSAKeyGenParameterSpec -import java.util.Calendar -import javax.crypto.Cipher -import javax.crypto.CipherInputStream -import javax.crypto.CipherOutputStream -import javax.crypto.IllegalBlockSizeException -import javax.crypto.KeyGenerator -import javax.crypto.NoSuchPaddingException -import javax.crypto.SecretKey -import javax.crypto.spec.GCMParameterSpec -import javax.crypto.spec.IvParameterSpec -import javax.crypto.spec.SecretKeySpec -import javax.security.auth.x500.X500Principal - -object CompatUtil { - private val TAG = CompatUtil::class.java.simpleName - private const val ANDROID_KEY_STORE_PROVIDER = "AndroidKeyStore" - private const val AES_GCM_CIPHER_TYPE = "AES/GCM/NoPadding" - private const val AES_GCM_KEY_SIZE_IN_BITS = 128 - private const val AES_GCM_IV_LENGTH = 12 - private const val AES_LOCAL_PROTECTION_KEY_ALIAS = "aes_local_protection" - - private const val RSA_WRAP_LOCAL_PROTECTION_KEY_ALIAS = "rsa_wrap_local_protection" - private const val RSA_WRAP_CIPHER_TYPE = "RSA/NONE/PKCS1Padding" - private const val AES_WRAPPED_PROTECTION_KEY_SHARED_PREFERENCE = "aes_wrapped_local_protection" - - private const val SHARED_KEY_ANDROID_VERSION_WHEN_KEY_HAS_BEEN_GENERATED = "android_version_when_key_has_been_generated" - - private var sSecretKeyAndVersion: SecretKeyAndVersion? = null - - /** - * Returns the unique SecureRandom instance shared for all local storage encryption operations. - */ - private val prng: SecureRandom by lazy(LazyThreadSafetyMode.NONE) { SecureRandom() } - - /** - * Returns the AES key used for local storage encryption/decryption with AES/GCM. - * The key is created if it does not exist already in the keystore. - * From Marshmallow, this key is generated and operated directly from the android keystore. - * From KitKat and before Marshmallow, this key is stored in the application shared preferences - * wrapped by a RSA key generated and operated directly from the android keystore. - * - * @param context the context holding the application shared preferences - */ - @Synchronized - @Throws(KeyStoreException::class, - CertificateException::class, - NoSuchAlgorithmException::class, - IOException::class, - NoSuchProviderException::class, - InvalidAlgorithmParameterException::class, - NoSuchPaddingException::class, - InvalidKeyException::class, - IllegalBlockSizeException::class, - UnrecoverableKeyException::class) - private fun getAesGcmLocalProtectionKey(context: Context): SecretKeyAndVersion { - if (sSecretKeyAndVersion == null) { - val keyStore = KeyStore.getInstance(ANDROID_KEY_STORE_PROVIDER) - keyStore.load(null) - - Timber.i(TAG, "Loading local protection key") - - var key: SecretKey? - - val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context) - // Get the version of Android when the key has been generated, default to the current version of the system. In this case, the - // key will be generated - val androidVersionWhenTheKeyHasBeenGenerated = sharedPreferences - .getInt(SHARED_KEY_ANDROID_VERSION_WHEN_KEY_HAS_BEEN_GENERATED, Build.VERSION.SDK_INT) - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - if (keyStore.containsAlias(AES_LOCAL_PROTECTION_KEY_ALIAS)) { - Timber.i(TAG, "AES local protection key found in keystore") - key = keyStore.getKey(AES_LOCAL_PROTECTION_KEY_ALIAS, null) as SecretKey - } else { - // Check if a key has been created on version < M (in case of OS upgrade) - key = readKeyApiL(sharedPreferences, keyStore) - - if (key == null) { - Timber.i(TAG, "Generating AES key with keystore") - val generator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES, ANDROID_KEY_STORE_PROVIDER) - generator.init( - KeyGenParameterSpec.Builder(AES_LOCAL_PROTECTION_KEY_ALIAS, - KeyProperties.PURPOSE_ENCRYPT or KeyProperties.PURPOSE_DECRYPT) - .setBlockModes(KeyProperties.BLOCK_MODE_GCM) - .setKeySize(AES_GCM_KEY_SIZE_IN_BITS) - .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) - .build()) - key = generator.generateKey() - - sharedPreferences.edit { - putInt(SHARED_KEY_ANDROID_VERSION_WHEN_KEY_HAS_BEEN_GENERATED, Build.VERSION.SDK_INT) - } - } - } - } else { - key = readKeyApiL(sharedPreferences, keyStore) - - if (key == null) { - Timber.i(TAG, "Generating RSA key pair with keystore") - val generator = KeyPairGenerator.getInstance(KeyProperties.KEY_ALGORITHM_RSA, ANDROID_KEY_STORE_PROVIDER) - val start = Calendar.getInstance() - val end = Calendar.getInstance() - end.add(Calendar.YEAR, 10) - - generator.initialize( - KeyPairGeneratorSpec.Builder(context) - .setAlgorithmParameterSpec(RSAKeyGenParameterSpec(2048, RSAKeyGenParameterSpec.F4)) - .setAlias(RSA_WRAP_LOCAL_PROTECTION_KEY_ALIAS) - .setSubject(X500Principal("CN=matrix-android-sdk")) - .setStartDate(start.time) - .setEndDate(end.time) - .setSerialNumber(BigInteger.ONE) - .build()) - val keyPair = generator.generateKeyPair() - - Timber.i(TAG, "Generating wrapped AES key") - - val aesKeyRaw = ByteArray(AES_GCM_KEY_SIZE_IN_BITS / java.lang.Byte.SIZE) - prng.nextBytes(aesKeyRaw) - key = SecretKeySpec(aesKeyRaw, "AES") - - val cipher = Cipher.getInstance(RSA_WRAP_CIPHER_TYPE) - cipher.init(Cipher.WRAP_MODE, keyPair.public) - val wrappedAesKey = cipher.wrap(key) - - sharedPreferences.edit { - putString(AES_WRAPPED_PROTECTION_KEY_SHARED_PREFERENCE, Base64.encodeToString(wrappedAesKey, 0)) - putInt(SHARED_KEY_ANDROID_VERSION_WHEN_KEY_HAS_BEEN_GENERATED, Build.VERSION.SDK_INT) - } - } - } - - sSecretKeyAndVersion = SecretKeyAndVersion(key!!, androidVersionWhenTheKeyHasBeenGenerated) - } - - return sSecretKeyAndVersion!! - } - - /** - * Read the key, which may have been stored when the OS was < M - * - * @param sharedPreferences shared pref - * @param keyStore key store - * @return the key if it exists or null - */ - @Throws(KeyStoreException::class, - NoSuchPaddingException::class, - NoSuchAlgorithmException::class, - InvalidKeyException::class, - UnrecoverableKeyException::class) - private fun readKeyApiL(sharedPreferences: SharedPreferences, keyStore: KeyStore): SecretKey? { - val wrappedAesKeyString = sharedPreferences.getString(AES_WRAPPED_PROTECTION_KEY_SHARED_PREFERENCE, null) - if (wrappedAesKeyString != null && keyStore.containsAlias(RSA_WRAP_LOCAL_PROTECTION_KEY_ALIAS)) { - Timber.i(TAG, "RSA + wrapped AES local protection keys found in keystore") - val privateKey = keyStore.getKey(RSA_WRAP_LOCAL_PROTECTION_KEY_ALIAS, null) as PrivateKey - val wrappedAesKey = Base64.decode(wrappedAesKeyString, 0) - val cipher = Cipher.getInstance(RSA_WRAP_CIPHER_TYPE) - cipher.init(Cipher.UNWRAP_MODE, privateKey) - return cipher.unwrap(wrappedAesKey, "AES", Cipher.SECRET_KEY) as SecretKey - } - - // Key does not exist - return null - } - - /** - * Create a CipherOutputStream instance. - * Before Kitkat, this method will return out as local storage encryption is not implemented for - * devices before KitKat. - * - * @param out the output stream - * @param context the context holding the application shared preferences - */ - @Throws(IOException::class, - CertificateException::class, - NoSuchAlgorithmException::class, - UnrecoverableKeyException::class, - InvalidKeyException::class, - InvalidAlgorithmParameterException::class, - NoSuchPaddingException::class, - NoSuchProviderException::class, - KeyStoreException::class, - IllegalBlockSizeException::class) - fun createCipherOutputStream(out: OutputStream, context: Context): OutputStream? { - val keyAndVersion = getAesGcmLocalProtectionKey(context) - - val cipher = Cipher.getInstance(AES_GCM_CIPHER_TYPE) - val iv: ByteArray - - if (keyAndVersion.androidVersionWhenTheKeyHasBeenGenerated >= Build.VERSION_CODES.M) { - cipher.init(Cipher.ENCRYPT_MODE, keyAndVersion.secretKey) - iv = cipher.iv - } else { - iv = ByteArray(AES_GCM_IV_LENGTH) - prng.nextBytes(iv) - cipher.init(Cipher.ENCRYPT_MODE, keyAndVersion.secretKey, IvParameterSpec(iv)) - } - - if (iv.size != AES_GCM_IV_LENGTH) { - Timber.e(TAG, "Invalid IV length ${iv.size}") - return null - } - - out.write(iv.size) - out.write(iv) - - return CipherOutputStream(out, cipher) - } - - /** - * Create a CipherInputStream instance. - * Warning, if inputStream is not an encrypted stream, it's up to the caller to close and reopen inputStream, because the stream has been read. - * - * @param inputStream the input stream - * @param context the context holding the application shared preferences - * @return inputStream, or the created InputStream, or null if the InputStream inputStream does not contain encrypted data - */ - @Throws(NoSuchPaddingException::class, - NoSuchAlgorithmException::class, - CertificateException::class, - InvalidKeyException::class, - KeyStoreException::class, - UnrecoverableKeyException::class, - IllegalBlockSizeException::class, - NoSuchProviderException::class, - InvalidAlgorithmParameterException::class, - IOException::class) - fun createCipherInputStream(inputStream: InputStream, context: Context): InputStream? { - val ivLen = inputStream.read() - if (ivLen != AES_GCM_IV_LENGTH) { - Timber.e(TAG, "Invalid IV length $ivLen") - return null - } - - val iv = ByteArray(AES_GCM_IV_LENGTH) - inputStream.read(iv) - - val cipher = Cipher.getInstance(AES_GCM_CIPHER_TYPE) - - val keyAndVersion = getAesGcmLocalProtectionKey(context) - - val spec: AlgorithmParameterSpec = if (keyAndVersion.androidVersionWhenTheKeyHasBeenGenerated >= Build.VERSION_CODES.M) { - GCMParameterSpec(AES_GCM_KEY_SIZE_IN_BITS, iv) - } else { - IvParameterSpec(iv) - } - - cipher.init(Cipher.DECRYPT_MODE, keyAndVersion.secretKey, spec) - - return CipherInputStream(inputStream, cipher) - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/FileSaver.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/FileSaver.kt index fb5e3a5774..3fcf35c127 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/FileSaver.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/FileSaver.kt @@ -24,7 +24,7 @@ import java.io.InputStream * Save an input stream to a file with Okio */ @WorkerThread -fun writeToFile(inputStream: InputStream, outputFile: File) { +internal fun writeToFile(inputStream: InputStream, outputFile: File) { // Ensure the parent folder exists, else it will crash outputFile.parentFile?.mkdirs() diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/JsonCanonicalizer.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/JsonCanonicalizer.kt index a34b91a70b..5994cbcf93 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/JsonCanonicalizer.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/JsonCanonicalizer.kt @@ -28,7 +28,7 @@ import java.util.TreeSet * Build canonical Json * Doc: https://matrix.org/docs/spec/appendices.html#canonical-json */ -object JsonCanonicalizer { +internal object JsonCanonicalizer { fun <T> getCanonicalJson(type: Class<T>, o: T): String { val adapter = MoshiProvider.providesMoshi().adapter<T>(type) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/LiveDataUtils.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/LiveDataUtils.kt deleted file mode 100644 index 80c3b83226..0000000000 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/LiveDataUtils.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2020 The Matrix.org Foundation C.I.C. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.matrix.android.sdk.internal.util - -import androidx.lifecycle.LiveData -import androidx.lifecycle.MediatorLiveData - -object LiveDataUtils { - - fun <FIRST, SECOND, OUT> combine(firstSource: LiveData<FIRST>, - secondSource: LiveData<SECOND>, - mapper: (FIRST, SECOND) -> OUT): LiveData<OUT> { - return MediatorLiveData<OUT>().apply { - var firstValue: FIRST? = null - var secondValue: SECOND? = null - - val valueDispatcher = { - firstValue?.let { safeFirst -> - secondValue?.let { safeSecond -> - val mappedValue = mapper(safeFirst, safeSecond) - postValue(mappedValue) - } - } - } - - addSource(firstSource) { - firstValue = it - valueDispatcher() - } - - addSource(secondSource) { - secondValue = it - valueDispatcher() - } - } - } -} diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Monarchy.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Monarchy.kt index afe77d76d5..6152eacae5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Monarchy.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Monarchy.kt @@ -26,7 +26,7 @@ internal suspend fun <T> Monarchy.awaitTransaction(transaction: suspend (realm: return awaitTransaction(realmConfiguration, transaction) } -fun <T : RealmModel> Monarchy.fetchCopied(query: (Realm) -> T?): T? { +internal fun <T : RealmModel> Monarchy.fetchCopied(query: (Realm) -> T?): T? { val ref = AtomicReference<T>() doWithRealm { realm -> val result = query.invoke(realm)?.let { @@ -37,7 +37,7 @@ fun <T : RealmModel> Monarchy.fetchCopied(query: (Realm) -> T?): T? { return ref.get() } -fun <U, T : RealmModel> Monarchy.fetchCopyMap(query: (Realm) -> T?, map: (T, realm: Realm) -> U): U? { +internal fun <U, T : RealmModel> Monarchy.fetchCopyMap(query: (Realm) -> T?, map: (T, realm: Realm) -> U): U? { val ref = AtomicReference<U?>() doWithRealm { realm -> val result = query.invoke(realm)?.let { diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Normalizer.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Normalizer.kt index 0e9c885394..0510521127 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Normalizer.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/Normalizer.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.util import java.text.Normalizer import javax.inject.Inject -class Normalizer @Inject constructor() { +internal class Normalizer @Inject constructor() { fun normalize(input: String): String { return Normalizer.normalize(input.lowercase(), Normalizer.Form.NFD) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/database/RealmMigrator.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/database/RealmMigrator.kt index b0f6794468..8084ad89a2 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/database/RealmMigrator.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/util/database/RealmMigrator.kt @@ -20,7 +20,7 @@ import io.realm.DynamicRealm import io.realm.RealmObjectSchema import timber.log.Timber -abstract class RealmMigrator(private val realm: DynamicRealm, +internal abstract class RealmMigrator(private val realm: DynamicRealm, private val targetSchemaVersion: Int) { open fun perform() { Timber.d("Migrate ${realm.configuration.realmFileName} to $targetSchemaVersion") diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/SessionWorkerParams.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/SessionWorkerParams.kt index c6c038d2d2..de36b85660 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/SessionWorkerParams.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/worker/SessionWorkerParams.kt @@ -20,7 +20,7 @@ package org.matrix.android.sdk.internal.worker * Note about the Worker usage: * The workers we chain, or when using the append strategy, should never return Result.Failure(), else the chain will be broken forever */ -interface SessionWorkerParams { +internal interface SessionWorkerParams { val sessionId: String /** diff --git a/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXDeviceInfo.java b/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXDeviceInfo.java index 1014ceda0e..4612b8d6ff 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXDeviceInfo.java +++ b/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXDeviceInfo.java @@ -20,10 +20,9 @@ import java.io.Serializable; import java.util.List; import java.util.Map; -/* - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose +/** + * <b>IMPORTANT:</b> This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose */ - public class MXDeviceInfo implements Serializable { private static final long serialVersionUID = 20129670646382964L; diff --git a/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXOlmInboundGroupSession2.java b/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXOlmInboundGroupSession2.java index 7277a86e9a..c6a8c1443c 100755 --- a/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXOlmInboundGroupSession2.java +++ b/matrix-sdk-android/src/main/java/org/matrix/androidsdk/crypto/data/MXOlmInboundGroupSession2.java @@ -23,11 +23,9 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; -/* - * IMPORTANT: This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose - */ - /** + * <b>IMPORTANT:</b> This class is imported from Riot-Android to be able to perform a migration. Do not use it for any other purpose + * * This class adds more context to a OLMInboundGroupSession object. * This allows additional checks. The class implements NSCoding so that the context can be stored. */ diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/RecoveryKeyTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/RecoveryKeyTest.kt index 4e4548b197..d4c9da2986 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/RecoveryKeyTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/keysbackup/util/RecoveryKeyTest.kt @@ -22,6 +22,9 @@ import org.junit.Assert.assertFalse import org.junit.Assert.assertTrue import org.junit.Test import org.matrix.android.sdk.MatrixTest +import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey +import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey +import org.matrix.android.sdk.api.session.crypto.keysbackup.isValidRecoveryKey class RecoveryKeyTest : MatrixTest { diff --git a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/store/db/HelperTest.kt b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/store/db/HelperTest.kt index b50d0581b0..39b3c5c731 100644 --- a/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/store/db/HelperTest.kt +++ b/matrix-sdk-android/src/test/java/org/matrix/android/sdk/internal/crypto/store/db/HelperTest.kt @@ -19,7 +19,7 @@ package org.matrix.android.sdk.internal.crypto.store.db import org.junit.Assert.assertEquals import org.junit.Test import org.matrix.android.sdk.MatrixTest -import org.matrix.android.sdk.internal.util.md5 +import org.matrix.android.sdk.api.util.md5 class HelperTest : MatrixTest { diff --git a/tools/check/check_code_quality.sh b/tools/check/check_code_quality.sh index 9535ff9efb..e40d3635e8 100755 --- a/tools/check/check_code_quality.sh +++ b/tools/check/check_code_quality.sh @@ -66,7 +66,7 @@ echo "Search for forbidden patterns in code..." ${searchForbiddenStringsScript} ./tools/check/forbidden_strings_in_code.txt \ ./matrix-sdk-android/src/main/java \ - ./matrix-sdk-android-rx/src/main/java \ + ./matrix-sdk-android-flow/src/main/java \ ./vector/src/main/java \ ./vector/src/debug/java \ ./vector/src/release/java \ @@ -80,10 +80,22 @@ echo "Search for forbidden patterns specific for SDK code..." ${searchForbiddenStringsScript} ./tools/check/forbidden_strings_in_code_sdk.txt \ ./matrix-sdk-android/src \ - ./matrix-sdk-android-rx/src + ./matrix-sdk-android-flow/src resultForbiddenStringInCodeSdk=$? +echo +echo "Search for forbidden patterns specific for App code..." + +${searchForbiddenStringsScript} ./tools/check/forbidden_strings_in_code_app.txt \ + ./vector/src/main/java \ + ./vector/src/debug/java \ + ./vector/src/release/java \ + ./vector/src/fdroid/java \ + ./vector/src/gplay/java + +resultForbiddenStringInCodeApp=$? + echo echo "Search for forbidden patterns in resources..." @@ -131,7 +143,7 @@ echo "Search for kotlin files with more than ${maxLines} lines..." ${checkLongFilesScript} ${maxLines} \ ./matrix-sdk-android/src/main/java \ - ./matrix-sdk-android-rx/src/main/java \ + ./matrix-sdk-android-flow/src/main/java \ ./vector/src/androidTest/java \ ./vector/src/debug/java \ ./vector/src/fdroid/java \ @@ -167,6 +179,7 @@ echo if [[ ${resultNbOfDrawable} -eq 0 ]] \ && [[ ${resultForbiddenStringInCode} -eq 0 ]] \ && [[ ${resultForbiddenStringInCodeSdk} -eq 0 ]] \ + && [[ ${resultForbiddenStringInCodeApp} -eq 0 ]] \ && [[ ${resultForbiddenStringInResource} -eq 0 ]] \ && [[ ${resultForbiddenStringInLayout} -eq 0 ]] \ && [[ ${resultLongFiles} -eq 0 ]] \ diff --git a/tools/check/forbidden_strings_in_code_app.txt b/tools/check/forbidden_strings_in_code_app.txt new file mode 100644 index 0000000000..0715030e8f --- /dev/null +++ b/tools/check/forbidden_strings_in_code_app.txt @@ -0,0 +1,18 @@ +# +# Copyright 2022 New Vector Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +### You should not use code from the SDK package `org.matrix.android.sdk.internal`. Either move the code to the package `org.matrix.android.sdk.api`, or add a proper API to access this code, and add `internal` keyword SDK side. +import org.matrix.android.sdk.internal diff --git a/tools/hs_diag.py b/tools/hs_diag.py index 7d7a947c4c..50f117bc8e 100755 --- a/tools/hs_diag.py +++ b/tools/hs_diag.py @@ -65,6 +65,6 @@ for item in items: print("# " + item[0] + " (" + item[1] + ")") print("====================================================================================================") if item[2]: - os.system("curl -s -X GET '" + item[1] + "' | python -m json.tool") + os.system("curl -s -X GET '" + item[1] + "' | python3 -m json.tool") else: - os.system("curl -s -X POST --data $'{}' '" + item[1] + "' | python -m json.tool") + os.system("curl -s -X POST --data $'{}' '" + item[1] + "' | python3 -m json.tool") diff --git a/vector-config/src/main/res/values/config-settings.xml b/vector-config/src/main/res/values/config-settings.xml index 40fc68bbae..b6d1c6676c 100755 --- a/vector-config/src/main/res/values/config-settings.xml +++ b/vector-config/src/main/res/values/config-settings.xml @@ -28,6 +28,8 @@ <bool name="settings_interface_bubble_visible">true</bool> <bool name="settings_interface_bubble_default">false</bool> + <bool name="settings_presence_visible">false</bool> + <bool name="settings_presence_user_always_appears_offline_default">false</bool> <!-- Level 1: Voice and video --> diff --git a/vector-config/src/main/res/values/urls.xml b/vector-config/src/main/res/values/urls.xml index 22e3a9ac72..70f5227f5f 100644 --- a/vector-config/src/main/res/values/urls.xml +++ b/vector-config/src/main/res/values/urls.xml @@ -3,4 +3,5 @@ <!-- This file contains url values--> <string name="threads_learn_more_url" translatable="false">https://element.io/help#threads</string> + <string name="ftue_ems_url">https://element.io/ems</string> </resources> \ No newline at end of file diff --git a/vector/build.gradle b/vector/build.gradle index b37eeefa8f..10060a5df2 100644 --- a/vector/build.gradle +++ b/vector/build.gradle @@ -18,7 +18,7 @@ ext.versionMinor = 4 // Note: even values are reserved for regular release, odd values for hotfix release. // When creating a hotfix, you should decrease the value, since the current value // is the value for the next regular release. -ext.versionPatch = 11 +ext.versionPatch = 12 ext.scVersion = 51 @@ -153,7 +153,6 @@ android { buildConfigField "Boolean", "enableLocationSharing", "true" buildConfigField "String", "mapTilerKey", "\"fU3vlMsMn4Jb6dnEIFsx\"" - buildConfigField "Boolean", "PRESENCE_SYNC_ENABLED", "true" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" @@ -234,7 +233,6 @@ android { buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false" // Set to true if you want to enable strict mode in debug buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false" - buildConfigField "Boolean", "ENABLE_LIVE_LOCATION_SHARING", "true" signingConfig signingConfigs.debug } @@ -244,7 +242,6 @@ android { buildConfigField "boolean", "LOW_PRIVACY_LOG_ENABLE", "false" buildConfigField "boolean", "ENABLE_STRICT_MODE_LOGS", "false" - buildConfigField "Boolean", "ENABLE_LIVE_LOCATION_SHARING", "false" postprocessing { removeUnusedCode true @@ -459,7 +456,8 @@ dependencies { implementation 'me.leolin:ShortcutBadger:1.1.22@aar' // Chat effects - implementation 'nl.dionsegijn:konfetti:1.3.2' + implementation 'nl.dionsegijn:konfetti-xml:2.0.2' + implementation 'com.github.jetradarmobile:android-snowfall:1.2.1' // DI implementation libs.dagger.hilt diff --git a/vector/src/androidTest/java/im/vector/app/EspressoExt.kt b/vector/src/androidTest/java/im/vector/app/EspressoExt.kt index 28564f7115..5fb404efe3 100644 --- a/vector/src/androidTest/java/im/vector/app/EspressoExt.kt +++ b/vector/src/androidTest/java/im/vector/app/EspressoExt.kt @@ -48,9 +48,9 @@ import org.hamcrest.Matcher import org.hamcrest.Matchers import org.hamcrest.StringDescription import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.crosssigning.PrivateKeysInfo import org.matrix.android.sdk.api.session.sync.SyncState import org.matrix.android.sdk.api.util.Optional -import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo import java.util.concurrent.TimeoutException object EspressoHelper { diff --git a/vector/src/debug/java/im/vector/app/config/AnalyticsConfig.kt b/vector/src/debug/java/im/vector/app/config/AnalyticsConfig.kt index 34f2d4f92b..63f14f72f6 100644 --- a/vector/src/debug/java/im/vector/app/config/AnalyticsConfig.kt +++ b/vector/src/debug/java/im/vector/app/config/AnalyticsConfig.kt @@ -21,7 +21,7 @@ import im.vector.app.features.analytics.AnalyticsConfig val analyticsConfig: AnalyticsConfig = object : AnalyticsConfig { override val isEnabled = BuildConfig.APPLICATION_ID == "im.vector.app.debug" - override val postHogHost = "https://posthog-poc.lab.element.dev" - override val postHogApiKey = "rs-pJjsYJTuAkXJfhaMmPUNBhWliDyTKLOOxike6ck8" + override val postHogHost = "https://posthog.element.dev" + override val postHogApiKey = "phc_VtA1L35nw3aeAtHIx1ayrGdzGkss7k1xINeXcoIQzXN" override val policyLink = "https://element.io/cookie-policy" } diff --git a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt index a2b2b44ce3..cc69cfd426 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/DebugMenuActivity.kt @@ -49,7 +49,6 @@ import im.vector.lib.ui.styles.debug.DebugVectorButtonStylesDarkActivity import im.vector.lib.ui.styles.debug.DebugVectorButtonStylesLightActivity import im.vector.lib.ui.styles.debug.DebugVectorTextViewDarkActivity import im.vector.lib.ui.styles.debug.DebugVectorTextViewLightActivity -import org.matrix.android.sdk.internal.crypto.verification.qrcode.toQrCodeData import timber.log.Timber import javax.inject.Inject @@ -251,7 +250,7 @@ class DebugMenuActivity : VectorBaseActivity<ActivityDebugMenuBinding>() { // renderQrCode(QrCodeScannerActivity.getResultText(data) ?: "") val result = QrCodeScannerActivity.getResultText(activityResult.data)!! - val qrCodeData = result.toQrCodeData() + val qrCodeData = null // This is now internal: result.toQrCodeData() Timber.e("qrCodeData: $qrCodeData") if (result.length != buffer.size) { @@ -265,6 +264,8 @@ class DebugMenuActivity : VectorBaseActivity<ActivityDebugMenuBinding>() { } } } + // Ensure developer will see that this cannot work anymore + error("toQrCodeData() is now internal") } } } diff --git a/vector/src/debug/java/im/vector/app/features/debug/settings/OverrideDropdownView.kt b/vector/src/debug/java/im/vector/app/features/debug/settings/OverrideDropdownView.kt index 48ec44f909..b8f89eaf88 100644 --- a/vector/src/debug/java/im/vector/app/features/debug/settings/OverrideDropdownView.kt +++ b/vector/src/debug/java/im/vector/app/features/debug/settings/OverrideDropdownView.kt @@ -24,7 +24,6 @@ import android.view.View import android.widget.AdapterView import android.widget.ArrayAdapter import android.widget.LinearLayout -import im.vector.app.R import im.vector.app.databinding.ViewBooleanDropdownBinding class OverrideDropdownView @JvmOverloads constructor( diff --git a/vector/src/main/java/im/vector/app/AppStateHandler.kt b/vector/src/main/java/im/vector/app/AppStateHandler.kt index 57da0f4e24..793ed685b1 100644 --- a/vector/src/main/java/im/vector/app/AppStateHandler.kt +++ b/vector/src/main/java/im/vector/app/AppStateHandler.kt @@ -18,10 +18,13 @@ package im.vector.app import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.asFlow import arrow.core.Option import arrow.core.getOrElse import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.utils.BehaviorDataSource +import im.vector.app.features.analytics.AnalyticsTracker +import im.vector.app.features.analytics.plan.UserProperties import im.vector.app.features.session.coroutineScope import im.vector.app.features.ui.UiStateRepository import kotlinx.coroutines.CoroutineScope @@ -30,6 +33,7 @@ import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach @@ -37,6 +41,7 @@ import kotlinx.coroutines.launch import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.group.model.GroupSummary +import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.room.model.RoomSummary import javax.inject.Inject import javax.inject.Singleton @@ -58,7 +63,8 @@ fun RoomGroupingMethod.group() = (this as? RoomGroupingMethod.ByLegacyGroup)?.gr class AppStateHandler @Inject constructor( private val sessionDataSource: ActiveSessionDataSource, private val uiStateRepository: UiStateRepository, - private val activeSessionHolder: ActiveSessionHolder + private val activeSessionHolder: ActiveSessionHolder, + private val analyticsTracker: AnalyticsTracker ) : DefaultLifecycleObserver { private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) @@ -133,11 +139,23 @@ class AppStateHandler @Inject constructor( } else { setCurrentGroup(uiStateRepository.getSelectedGroup(session.sessionId), session) } + observeSyncStatus(session) } } .launchIn(coroutineScope) } + private fun observeSyncStatus(session: Session) { + session.getSyncStatusLive() + .asFlow() + .filterIsInstance<SyncStatusService.Status.IncrementalSyncDone>() + .map { session.spaceService().getRootSpaceSummaries().size } + .distinctUntilChanged() + .onEach { spacesNumber -> + analyticsTracker.updateUserProperties(UserProperties(numSpaces = spacesNumber)) + }.launchIn(session.coroutineScope) + } + fun safeActiveSpaceId(): String? { return (selectedSpaceDataSourceSc.currentValue?.orNull()?.first as? RoomGroupingMethod.BySpace)?.spaceSummary?.roomId } diff --git a/vector/src/main/java/im/vector/app/AutoRageShaker.kt b/vector/src/main/java/im/vector/app/AutoRageShaker.kt index 43283254b1..195e2f68dc 100644 --- a/vector/src/main/java/im/vector/app/AutoRageShaker.kt +++ b/vector/src/main/java/im/vector/app/AutoRageShaker.kt @@ -17,9 +17,11 @@ package im.vector.app import android.content.SharedPreferences +import androidx.lifecycle.asFlow import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.features.rageshake.BugReporter import im.vector.app.features.rageshake.ReportType +import im.vector.app.features.session.coroutineScope import im.vector.app.features.settings.VectorPreferences import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers @@ -34,6 +36,7 @@ import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toContent +import org.matrix.android.sdk.api.session.initsync.SyncStatusService import timber.log.Timber import javax.inject.Inject import javax.inject.Singleton @@ -62,10 +65,11 @@ class AutoRageShaker @Inject constructor( private val e2eDetectedFlow = MutableSharedFlow<E2EMessageDetected>(replay = 0) private val matchingRSRequestFlow = MutableSharedFlow<Event>(replay = 0) - + private var hasSynced = false + private var preferenceEnabled = false fun initialize() { observeActiveSession() - enable(vectorPreferences.labsAutoReportUISI()) + preferenceEnabled = vectorPreferences.labsAutoReportUISI() // It's a singleton... vectorPreferences.subscribeToChanges(this) @@ -74,7 +78,7 @@ class AutoRageShaker @Inject constructor( e2eDetectedFlow .onEach { sendRageShake(it) - delay(2_000) + delay(60_000) } .catch { cause -> Timber.w(cause, "Failed to RS") @@ -84,7 +88,7 @@ class AutoRageShaker @Inject constructor( matchingRSRequestFlow .onEach { sendMatchingRageShake(it) - delay(2_000) + delay(60_000) } .catch { cause -> Timber.w(cause, "Failed to send matching rageshake") @@ -93,14 +97,7 @@ class AutoRageShaker @Inject constructor( } override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { - enable(vectorPreferences.labsAutoReportUISI()) - } - - var _enabled = false - fun enable(enabled: Boolean) { - if (enabled == _enabled) return - _enabled = enabled - detector.enabled = enabled + preferenceEnabled = vectorPreferences.labsAutoReportUISI() } private fun observeActiveSession() { @@ -115,7 +112,6 @@ class AutoRageShaker @Inject constructor( } fun decryptionErrorDetected(target: E2EMessageDetected) { - if (target.source == UISIEventSource.INITIAL_SYNC) return if (activeSessionHolder.getSafeActiveSession()?.sessionId != currentActiveSessionId) return val shouldSendRS = synchronized(alreadyReportedUisi) { val reportInfo = ReportInfo(target.roomId, target.sessionId) @@ -148,7 +144,6 @@ class AutoRageShaker @Inject constructor( append("\"room_id\": \"${target.roomId}\",") append("\"sender_key\": \"${target.senderKey}\",") append("\"device_id\": \"${target.senderDeviceId}\",") - append("\"source\": \"${target.source}\",") append("\"user_id\": \"${target.senderUserId}\",") append("\"session_id\": \"${target.sessionId}\"") append("}") @@ -245,6 +240,9 @@ class AutoRageShaker @Inject constructor( override val reciprocateToDeviceEventType: String get() = AUTO_RS_REQUEST + override val enabled: Boolean + get() = this@AutoRageShaker.preferenceEnabled && this@AutoRageShaker.hasSynced + override fun uisiDetected(source: E2EMessageDetected) { decryptionErrorDetected(source) } @@ -261,7 +259,14 @@ class AutoRageShaker @Inject constructor( return } this.currentActiveSessionId = sessionId - this.detector.enabled = _enabled + + hasSynced = session.hasAlreadySynced() + session.getSyncStatusLive() + .asFlow() + .onEach { + hasSynced = it !is SyncStatusService.Status.InitialSyncProgressing + } + .launchIn(session.coroutineScope) activeSessionIds.add(sessionId) session.addListener(this) session.addEventStreamListener(detector) diff --git a/vector/src/main/java/im/vector/app/UISIDetector.kt b/vector/src/main/java/im/vector/app/UISIDetector.kt index d6a4805e78..6157537743 100644 --- a/vector/src/main/java/im/vector/app/UISIDetector.kt +++ b/vector/src/main/java/im/vector/app/UISIDetector.kt @@ -16,33 +16,28 @@ package im.vector.app +import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.LiveEventListener import org.matrix.android.sdk.api.session.events.model.Event +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.util.JsonDict -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent import timber.log.Timber import java.util.Timer import java.util.TimerTask import java.util.concurrent.Executors -enum class UISIEventSource { - INITIAL_SYNC, - INCREMENTAL_SYNC, - PAGINATION -} - data class E2EMessageDetected( val eventId: String, val roomId: String, val senderUserId: String, val senderDeviceId: String, val senderKey: String, - val sessionId: String, - val source: UISIEventSource) { + val sessionId: String + ) { companion object { - fun fromEvent(event: Event, roomId: String, source: UISIEventSource): E2EMessageDetected { + fun fromEvent(event: Event, roomId: String): E2EMessageDetected { val encryptedContent = event.content.toModel<EncryptedEventContent>() return E2EMessageDetected( @@ -51,8 +46,7 @@ data class E2EMessageDetected( senderUserId = event.senderId ?: "", senderDeviceId = encryptedContent?.deviceId ?: "", senderKey = encryptedContent?.senderKey ?: "", - sessionId = encryptedContent?.sessionId ?: "", - source = source + sessionId = encryptedContent?.sessionId ?: "" ) } } @@ -61,6 +55,7 @@ data class E2EMessageDetected( class UISIDetector : LiveEventListener { interface UISIDetectorCallback { + val enabled: Boolean val reciprocateToDeviceEventType: String fun uisiDetected(source: E2EMessageDetected) fun uisiReciprocateRequest(source: Event) @@ -68,30 +63,16 @@ class UISIDetector : LiveEventListener { var callback: UISIDetectorCallback? = null - private val trackedEvents = mutableListOf<Pair<E2EMessageDetected, TimerTask>>() + private val trackedEvents = mutableMapOf<String, TimerTask>() private val executor = Executors.newSingleThreadExecutor() private val timer = Timer() private val timeoutMillis = 30_000L - var enabled = false + private val enabled: Boolean get() = callback?.enabled.orFalse() - override fun onLiveEvent(roomId: String, event: Event) { - if (!enabled) return - if (!event.isEncrypted()) return - executor.execute { - handleEventReceived(E2EMessageDetected.fromEvent(event, roomId, UISIEventSource.INCREMENTAL_SYNC)) - } - } - - override fun onPaginatedEvent(roomId: String, event: Event) { - if (!enabled) return - if (!event.isEncrypted()) return - executor.execute { - handleEventReceived(E2EMessageDetected.fromEvent(event, roomId, UISIEventSource.PAGINATION)) - } - } - - override fun onEventDecrypted(eventId: String, roomId: String, clearEvent: JsonDict) { - if (!enabled) return + override fun onEventDecrypted(event: Event, clearEvent: JsonDict) { + val eventId = event.eventId + val roomId = event.roomId + if (!enabled || eventId == null || roomId == null) return executor.execute { unTrack(eventId, roomId) } @@ -104,57 +85,43 @@ class UISIDetector : LiveEventListener { } } - override fun onEventDecryptionError(eventId: String, roomId: String, throwable: Throwable) { - if (!enabled) return - executor.execute { - unTrack(eventId, roomId)?.let { - triggerUISI(it) - } -// if (throwable is MXCryptoError.OlmError) { -// if (throwable.olmException.message == "UNKNOWN_MESSAGE_INDEX") { -// unTrack(eventId, roomId)?.let { -// triggerUISI(it) -// } -// } -// } - } - } + override fun onEventDecryptionError(event: Event, throwable: Throwable) { + val eventId = event.eventId + val roomId = event.roomId + if (!enabled || eventId == null || roomId == null) return - private fun handleEventReceived(detectorEvent: E2EMessageDetected) { - if (!enabled) return - if (trackedEvents.any { it.first == detectorEvent }) { - Timber.w("## UISIDetector: Event ${detectorEvent.eventId} is already tracked") - } else { - // track it and start timer - val timeoutTask = object : TimerTask() { - override fun run() { - executor.execute { - unTrack(detectorEvent.eventId, detectorEvent.roomId) - Timber.v("## UISIDetector: Timeout on ${detectorEvent.eventId} ") - triggerUISI(detectorEvent) - } + val trackerId: String = trackerId(eventId, roomId) + if (trackedEvents.containsKey(trackerId)) { + Timber.w("## UISIDetector: Event $eventId is already tracked") + return + } + // track it and start timer + val timeoutTask = object : TimerTask() { + override fun run() { + executor.execute { + unTrack(eventId, roomId) + Timber.v("## UISIDetector: Timeout on $eventId") + triggerUISI(E2EMessageDetected.fromEvent(event, roomId)) } } - trackedEvents.add(detectorEvent to timeoutTask) - timer.schedule(timeoutTask, timeoutMillis) } + trackedEvents[trackerId] = timeoutTask + timer.schedule(timeoutTask, timeoutMillis) } + override fun onLiveEvent(roomId: String, event: Event) { } + + override fun onPaginatedEvent(roomId: String, event: Event) { } + + private fun trackerId(eventId: String, roomId: String): String = "$roomId-$eventId" + private fun triggerUISI(source: E2EMessageDetected) { if (!enabled) return Timber.i("## UISIDetector: Unable To Decrypt $source") callback?.uisiDetected(source) } - private fun unTrack(eventId: String, roomId: String): E2EMessageDetected? { - val index = trackedEvents.indexOfFirst { it.first.eventId == eventId && it.first.roomId == roomId } - return if (index != -1) { - trackedEvents.removeAt(index).let { - it.second.cancel() - it.first - } - } else { - null - } + private fun unTrack(eventId: String, roomId: String) { + trackedEvents.remove(trackerId(eventId, roomId))?.cancel() } } diff --git a/vector/src/main/java/im/vector/app/VectorApplication.kt b/vector/src/main/java/im/vector/app/VectorApplication.kt index f88d993d99..9658c54174 100644 --- a/vector/src/main/java/im/vector/app/VectorApplication.kt +++ b/vector/src/main/java/im/vector/app/VectorApplication.kt @@ -236,13 +236,13 @@ class VectorApplication : val sdkVersion = Matrix.getSdkVersion() val date = SimpleDateFormat("MM-dd HH:mm:ss.SSSZ", Locale.US).format(Date()) - Timber.v("----------------------------------------------------------------") - Timber.v("----------------------------------------------------------------") - Timber.v(" Application version: $appVersion") - Timber.v(" SDK version: $sdkVersion") - Timber.v(" Local time: $date") - Timber.v("----------------------------------------------------------------") - Timber.v("----------------------------------------------------------------\n\n\n\n") + Timber.d("----------------------------------------------------------------") + Timber.d("----------------------------------------------------------------") + Timber.d(" Application version: $appVersion") + Timber.d(" SDK version: $sdkVersion") + Timber.d(" Local time: $date") + Timber.d("----------------------------------------------------------------") + Timber.d("----------------------------------------------------------------\n\n\n\n") } override fun attachBaseContext(base: Context) { diff --git a/vector/src/main/java/im/vector/app/core/animations/Konfetti.kt b/vector/src/main/java/im/vector/app/core/animations/Konfetti.kt index 22764ac5bd..882891810b 100644 --- a/vector/src/main/java/im/vector/app/core/animations/Konfetti.kt +++ b/vector/src/main/java/im/vector/app/core/animations/Konfetti.kt @@ -20,9 +20,14 @@ import android.content.Context import androidx.annotation.ColorInt import androidx.core.content.ContextCompat import im.vector.app.R -import nl.dionsegijn.konfetti.KonfettiView -import nl.dionsegijn.konfetti.models.Shape -import nl.dionsegijn.konfetti.models.Size +import nl.dionsegijn.konfetti.core.Angle +import nl.dionsegijn.konfetti.core.Party +import nl.dionsegijn.konfetti.core.Position +import nl.dionsegijn.konfetti.core.Spread +import nl.dionsegijn.konfetti.core.emitter.Emitter +import nl.dionsegijn.konfetti.core.models.Shape +import nl.dionsegijn.konfetti.core.models.Size +import nl.dionsegijn.konfetti.xml.KonfettiView fun KonfettiView.play() { val confettiColors = listOf( @@ -35,16 +40,22 @@ fun KonfettiView.play() { R.color.palette_prune, R.color.palette_kiwi ) - build() - .addColors(confettiColors.toColorInt(context)) - .setDirection(0.0, 359.0) - .setSpeed(2f, 5f) - .setFadeOutEnabled(true) - .setTimeToLive(2000L) - .addShapes(Shape.Square, Shape.Circle) - .addSizes(Size(12)) - .setPosition(-50f, width + 50f, -50f, -50f) - .streamFor(150, 3000L) + val emitterConfig = Emitter(2000).perSecond(100) + val party = Party( + emitter = emitterConfig, + colors = confettiColors.toColorInt(context), + angle = Angle.Companion.BOTTOM, + spread = Spread.ROUND, + shapes = listOf(Shape.Square, Shape.Circle), + size = listOf(Size(12)), + speed = 2f, + maxSpeed = 5f, + fadeOutEnabled = true, + timeToLive = 2000L, + position = Position.Relative(0.0, 0.0).between(Position.Relative(1.0, 0.0)), + ) + reset() + start(party) } @ColorInt diff --git a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt index 53f0ab3eed..e3c0e718aa 100644 --- a/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/FragmentModule.kt @@ -103,6 +103,7 @@ import im.vector.app.features.onboarding.ftueauth.FtueAuthCaptchaFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthChooseDisplayNameFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthChooseProfilePictureFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthGenericTextInputFormFragment +import im.vector.app.features.onboarding.ftueauth.FtueAuthLegacyStyleCaptchaFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthLoginFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthPersonalizationCompleteFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthResetPasswordFragment @@ -115,6 +116,7 @@ import im.vector.app.features.onboarding.ftueauth.FtueAuthSplashFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthUseCaseFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthWaitForEmailFragment import im.vector.app.features.onboarding.ftueauth.FtueAuthWebFragment +import im.vector.app.features.onboarding.ftueauth.terms.FtueAuthLegacyStyleTermsFragment import im.vector.app.features.onboarding.ftueauth.terms.FtueAuthTermsFragment import im.vector.app.features.pin.PinFragment import im.vector.app.features.poll.create.CreatePollFragment @@ -409,6 +411,11 @@ interface FragmentModule { @FragmentKey(LoginWaitForEmailFragment2::class) fun bindLoginWaitForEmailFragment2(fragment: LoginWaitForEmailFragment2): Fragment + @Binds + @IntoMap + @FragmentKey(FtueAuthLegacyStyleCaptchaFragment::class) + fun bindFtueAuthLegacyStyleCaptchaFragment(fragment: FtueAuthLegacyStyleCaptchaFragment): Fragment + @Binds @IntoMap @FragmentKey(FtueAuthCaptchaFragment::class) @@ -474,6 +481,11 @@ interface FragmentModule { @FragmentKey(FtueAuthWebFragment::class) fun bindFtueAuthWebFragment(fragment: FtueAuthWebFragment): Fragment + @Binds + @IntoMap + @FragmentKey(FtueAuthLegacyStyleTermsFragment::class) + fun bindFtueAuthLegacyStyleTermsFragment(fragment: FtueAuthLegacyStyleTermsFragment): Fragment + @Binds @IntoMap @FragmentKey(FtueAuthTermsFragment::class) diff --git a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt index fdd6e3c2ba..0db7e4e8ea 100644 --- a/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt +++ b/vector/src/main/java/im/vector/app/core/di/SingletonModule.kt @@ -60,6 +60,7 @@ import org.matrix.android.sdk.api.auth.HomeServerHistoryService import org.matrix.android.sdk.api.legacy.LegacySessionImporter import org.matrix.android.sdk.api.raw.RawService import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import javax.inject.Singleton @InstallIn(SingletonComponent::class) @@ -121,7 +122,6 @@ object VectorStaticModule { applicationFlavor = BuildConfig.FLAVOR_DESCRIPTION, roomDisplayNameFallbackProvider = vectorRoomDisplayNameFallbackProvider, threadMessagesEnabledDefault = vectorPreferences.areThreadMessagesEnabled(), - presenceSyncEnabled = BuildConfig.PRESENCE_SYNC_ENABLED ) } @@ -152,6 +152,11 @@ object VectorStaticModule { return matrix.rawService() } + @Provides + fun providesLightweightSettingsStorage(matrix: Matrix): LightweightSettingsStorage { + return matrix.lightweightSettingsStorage() + } + @Provides fun providesHomeServerHistoryService(matrix: Matrix): HomeServerHistoryService { return matrix.homeServerHistoryService() diff --git a/vector/src/main/java/im/vector/app/core/dialogs/ManuallyVerifyDialog.kt b/vector/src/main/java/im/vector/app/core/dialogs/ManuallyVerifyDialog.kt index 9e318bf693..f3923fc4e0 100644 --- a/vector/src/main/java/im/vector/app/core/dialogs/ManuallyVerifyDialog.kt +++ b/vector/src/main/java/im/vector/app/core/dialogs/ManuallyVerifyDialog.kt @@ -21,7 +21,7 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R import im.vector.app.databinding.DialogDeviceVerifyBinding import org.matrix.android.sdk.api.extensions.getFingerprintHumanReadable -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo object ManuallyVerifyDialog { diff --git a/vector/src/main/java/im/vector/app/core/dialogs/UnrecognizedCertificateDialog.kt b/vector/src/main/java/im/vector/app/core/dialogs/UnrecognizedCertificateDialog.kt index f46737d6c6..415c82b330 100644 --- a/vector/src/main/java/im/vector/app/core/dialogs/UnrecognizedCertificateDialog.kt +++ b/vector/src/main/java/im/vector/app/core/dialogs/UnrecognizedCertificateDialog.kt @@ -21,10 +21,8 @@ import im.vector.app.R import im.vector.app.core.di.ActiveSessionHolder import im.vector.app.core.resources.StringProvider import im.vector.app.databinding.DialogSslFingerprintBinding -import org.matrix.android.sdk.internal.network.ssl.Fingerprint +import org.matrix.android.sdk.api.network.ssl.Fingerprint import timber.log.Timber -import java.util.HashMap -import java.util.HashSet import javax.inject.Inject /** diff --git a/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetMessagePreviewItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetMessagePreviewItem.kt index 14ba34cc52..b90956ad9e 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetMessagePreviewItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/bottomsheet/BottomSheetMessagePreviewItem.kt @@ -33,7 +33,7 @@ import im.vector.app.core.extensions.setTextOrHide import im.vector.app.core.glide.GlideApp import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer -import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider +import im.vector.app.features.home.room.detail.timeline.action.LocationUiData import im.vector.app.features.home.room.detail.timeline.item.BindingOptions import im.vector.app.features.home.room.detail.timeline.tools.findPillsAndProcess import im.vector.app.features.media.ImageContentRenderer @@ -71,13 +71,7 @@ abstract class BottomSheetMessagePreviewItem : VectorEpoxyModel<BottomSheetMessa var time: String? = null @EpoxyAttribute - var locationUrl: String? = null - - @EpoxyAttribute - var locationPinProvider: LocationPinProvider? = null - - @EpoxyAttribute - var locationOwnerId: String? = null + var locationUiData: LocationUiData? = null @EpoxyAttribute var movementMethod: MovementMethod? = null @@ -101,18 +95,15 @@ abstract class BottomSheetMessagePreviewItem : VectorEpoxyModel<BottomSheetMessa body.charSequence.findPillsAndProcess(coroutineScope) { it.bind(holder.body) } holder.timestamp.setTextOrHide(time) - if (locationUrl == null) { - holder.body.isVisible = true - holder.mapViewContainer.isVisible = false - } else { - holder.body.isVisible = false - holder.mapViewContainer.isVisible = true + holder.body.isVisible = locationUiData == null + holder.mapViewContainer.isVisible = locationUiData != null + locationUiData?.let { safeLocationUiData -> GlideApp.with(holder.staticMapImageView) - .load(locationUrl) + .load(safeLocationUiData.locationUrl) .apply(RequestOptions.centerCropTransform()) .into(holder.staticMapImageView) - locationPinProvider?.create(locationOwnerId) { pinDrawable -> + safeLocationUiData.locationPinProvider.create(safeLocationUiData.locationOwnerId) { pinDrawable -> GlideApp.with(holder.staticMapPinImageView) .load(pinDrawable) .into(holder.staticMapPinImageView) diff --git a/vector/src/main/java/im/vector/app/core/epoxy/profiles/BaseProfileMatrixItem.kt b/vector/src/main/java/im/vector/app/core/epoxy/profiles/BaseProfileMatrixItem.kt index e4b6124e19..956e1de92c 100644 --- a/vector/src/main/java/im/vector/app/core/epoxy/profiles/BaseProfileMatrixItem.kt +++ b/vector/src/main/java/im/vector/app/core/epoxy/profiles/BaseProfileMatrixItem.kt @@ -25,7 +25,7 @@ import im.vector.app.core.epoxy.onClick import im.vector.app.core.extensions.setTextOrHide import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.util.MatrixItem abstract class BaseProfileMatrixItem<T : ProfileMatrixItem.Holder> : VectorEpoxyModel<T>() { diff --git a/vector/src/main/java/im/vector/app/core/extensions/Collections.kt b/vector/src/main/java/im/vector/app/core/extensions/Collections.kt index 5168915c9c..d48875983d 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/Collections.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/Collections.kt @@ -18,3 +18,5 @@ package im.vector.app.core.extensions inline fun <reified T> List<T>.nextOrNull(index: Int) = getOrNull(index + 1) inline fun <reified T> List<T>.prevOrNull(index: Int) = getOrNull(index - 1) + +fun <T> List<T>.containsAllItems(vararg items: T) = this.containsAll(items.toList()) diff --git a/vector/src/main/java/im/vector/app/core/extensions/ResultExtensions.kt b/vector/src/main/java/im/vector/app/core/extensions/ResultExtensions.kt new file mode 100644 index 0000000000..bb2e9070ca --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/extensions/ResultExtensions.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.core.extensions + +@Suppress("UNCHECKED_CAST") // We're casting null failure results to R +inline fun <T, R> Result<T>.andThen(block: (T) -> Result<R>): Result<R> { + return when (val result = getOrNull()) { + null -> this as Result<R> + else -> block(result) + } +} diff --git a/vector/src/main/java/im/vector/app/core/extensions/UrlExtensions.kt b/vector/src/main/java/im/vector/app/core/extensions/UrlExtensions.kt index 5037f78445..749da0d987 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/UrlExtensions.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/UrlExtensions.kt @@ -19,8 +19,8 @@ package im.vector.app.core.extensions /** * Ex: "https://matrix.org/" -> "matrix.org" */ -fun String?.toReducedUrl(): String { +fun String?.toReducedUrl(keepSchema: Boolean = false): String { return (this ?: "") - .substringAfter("://") + .run { if (keepSchema) this else substringAfter("://") } .trim { it == '/' } } diff --git a/vector/src/main/java/im/vector/app/core/extensions/View.kt b/vector/src/main/java/im/vector/app/core/extensions/View.kt index 7ec86d3508..4b21063f0b 100644 --- a/vector/src/main/java/im/vector/app/core/extensions/View.kt +++ b/vector/src/main/java/im/vector/app/core/extensions/View.kt @@ -32,3 +32,12 @@ fun View.showKeyboard(andRequestFocus: Boolean = false) { val imm = context?.getSystemService<InputMethodManager>() imm?.showSoftInput(this, InputMethodManager.SHOW_IMPLICIT) } + +fun View.setHorizontalPadding(padding: Int) { + setPadding( + padding, + paddingTop, + padding, + paddingBottom + ) +} diff --git a/vector/src/main/java/im/vector/app/core/glide/ElementToDecryptOption.kt b/vector/src/main/java/im/vector/app/core/glide/ElementToDecryptOption.kt index 1888012450..f4f854406e 100644 --- a/vector/src/main/java/im/vector/app/core/glide/ElementToDecryptOption.kt +++ b/vector/src/main/java/im/vector/app/core/glide/ElementToDecryptOption.kt @@ -17,7 +17,7 @@ package im.vector.app.core.glide import com.bumptech.glide.load.Option -import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt const val ElementToDecryptOptionKey = "im.vector.app.core.glide.ElementToDecrypt" diff --git a/vector/src/main/java/im/vector/app/core/receiver/AlarmSyncBroadcastReceiver.kt b/vector/src/main/java/im/vector/app/core/receiver/AlarmSyncBroadcastReceiver.kt index c1135288aa..e81675d4f5 100644 --- a/vector/src/main/java/im/vector/app/core/receiver/AlarmSyncBroadcastReceiver.kt +++ b/vector/src/main/java/im/vector/app/core/receiver/AlarmSyncBroadcastReceiver.kt @@ -27,7 +27,7 @@ import androidx.core.content.getSystemService import im.vector.app.core.extensions.singletonEntryPoint import im.vector.app.core.platform.PendingIntentCompat import im.vector.app.core.services.VectorSyncService -import org.matrix.android.sdk.internal.session.sync.job.SyncService +import org.matrix.android.sdk.api.session.sync.job.SyncService import timber.log.Timber class AlarmSyncBroadcastReceiver : BroadcastReceiver() { diff --git a/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt b/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt index 8621c28d57..5dbea8dcc4 100644 --- a/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt +++ b/vector/src/main/java/im/vector/app/core/services/VectorSyncService.kt @@ -36,7 +36,7 @@ import im.vector.app.core.platform.PendingIntentCompat import im.vector.app.features.notifications.NotificationUtils import im.vector.app.features.settings.BackgroundSyncMode import org.matrix.android.sdk.api.Matrix -import org.matrix.android.sdk.internal.session.sync.job.SyncService +import org.matrix.android.sdk.api.session.sync.job.SyncService import timber.log.Timber import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/core/ui/views/ShieldImageView.kt b/vector/src/main/java/im/vector/app/core/ui/views/ShieldImageView.kt index 713c177099..a82a9a30b4 100644 --- a/vector/src/main/java/im/vector/app/core/ui/views/ShieldImageView.kt +++ b/vector/src/main/java/im/vector/app/core/ui/views/ShieldImageView.kt @@ -22,7 +22,7 @@ import androidx.annotation.DrawableRes import androidx.appcompat.widget.AppCompatImageView import androidx.core.view.isVisible import im.vector.app.R -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel class ShieldImageView @JvmOverloads constructor( context: Context, diff --git a/vector/src/main/java/im/vector/app/core/utils/LiveData.kt b/vector/src/main/java/im/vector/app/core/utils/LiveData.kt new file mode 100644 index 0000000000..922fd46235 --- /dev/null +++ b/vector/src/main/java/im/vector/app/core/utils/LiveData.kt @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.core.utils + +import androidx.lifecycle.LiveData +import androidx.lifecycle.MediatorLiveData + +fun <T1, T2, R> combineLatest(source1: LiveData<T1>, source2: LiveData<T2>, mapper: (T1, T2) -> R): LiveData<R> { + val combined = MediatorLiveData<R>() + var source1Result: T1? = null + var source2Result: T2? = null + + fun notify() { + if (source1Result != null && source2Result != null) { + combined.value = mapper(source1Result!!, source2Result!!) + } + } + + combined.addSource(source1) { + source1Result = it + notify() + } + combined.addSource(source2) { + source2Result = it + notify() + } + return combined +} diff --git a/vector/src/main/java/im/vector/app/features/VectorFeatures.kt b/vector/src/main/java/im/vector/app/features/VectorFeatures.kt index 992fa4d5a5..b2a62a42d3 100644 --- a/vector/src/main/java/im/vector/app/features/VectorFeatures.kt +++ b/vector/src/main/java/im/vector/app/features/VectorFeatures.kt @@ -42,5 +42,5 @@ class DefaultVectorFeatures : VectorFeatures { override fun isOnboardingUseCaseEnabled() = true override fun isOnboardingPersonalizeEnabled() = false override fun isOnboardingCombinedRegisterEnabled() = false - override fun isLiveLocationEnabled(): Boolean = BuildConfig.ENABLE_LIVE_LOCATION_SHARING + override fun isLiveLocationEnabled(): Boolean = false } diff --git a/vector/src/main/java/im/vector/app/features/analytics/plan/Signup.kt b/vector/src/main/java/im/vector/app/features/analytics/plan/Signup.kt new file mode 100644 index 0000000000..328340fd2f --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/analytics/plan/Signup.kt @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2021 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.analytics.plan + +import im.vector.app.features.analytics.itf.VectorAnalyticsEvent + +// GENERATED FILE, DO NOT EDIT. FOR MORE INFORMATION VISIT +// https://github.com/matrix-org/matrix-analytics-events/ + +/** + * Triggered once onboarding has completed, but only if the user registered a + * new account. + */ +data class Signup( + /** + * The type of authentication that was used to sign up. + */ + val authenticationType: AuthenticationType, +) : VectorAnalyticsEvent { + + enum class AuthenticationType { + /** + * Social login using Apple. + */ + Apple, + + /** + * Social login using Facebook. + */ + Facebook, + + /** + * Social login using GitHub. + */ + GitHub, + + /** + * Social login using GitLab. + */ + GitLab, + + /** + * Social login using Google. + */ + Google, + + /** + * Registration using some other mechanism such as fallback. + */ + Other, + + /** + * Registration with a username and password. + */ + Password, + + /** + * Registration using another SSO provider. + */ + SSO, + } + + override fun getName() = "Signup" + + override fun getProperties(): Map<String, Any>? { + return mutableMapOf<String, Any>().apply { + put("authenticationType", authenticationType.name) + }.takeIf { it.isNotEmpty() } + } +} diff --git a/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt b/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt index 6f3130ab23..d5f5dc583a 100644 --- a/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt +++ b/vector/src/main/java/im/vector/app/features/attachments/AttachmentTypeSelectorView.kt @@ -41,6 +41,7 @@ import im.vector.app.core.utils.PERMISSIONS_FOR_FOREGROUND_LOCATION_SHARING import im.vector.app.core.utils.PERMISSIONS_FOR_PICKING_CONTACT import im.vector.app.core.utils.PERMISSIONS_FOR_TAKING_PHOTO import im.vector.app.databinding.ViewAttachmentTypeSelectorBinding +import im.vector.app.features.attachments.AttachmentTypeSelectorView.Callback import kotlin.math.max private const val ANIMATION_DURATION = 250 diff --git a/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt b/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt index 830fd4e79d..fcc2a59ef8 100644 --- a/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/auth/ReAuthViewModel.kt @@ -25,7 +25,7 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel import org.matrix.android.sdk.api.auth.data.LoginFlowTypes import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding +import org.matrix.android.sdk.api.util.toBase64NoPadding import java.io.ByteArrayOutputStream class ReAuthViewModel @AssistedInject constructor( diff --git a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt index 449a740cf3..b9bf578daa 100644 --- a/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/VectorCallViewModel.kt @@ -16,7 +16,6 @@ package im.vector.app.features.call -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksViewModelFactory diff --git a/vector/src/main/java/im/vector/app/features/call/audio/API21AudioDeviceDetector.kt b/vector/src/main/java/im/vector/app/features/call/audio/API21AudioDeviceDetector.kt index eafd1eab20..15d213e017 100644 --- a/vector/src/main/java/im/vector/app/features/call/audio/API21AudioDeviceDetector.kt +++ b/vector/src/main/java/im/vector/app/features/call/audio/API21AudioDeviceDetector.kt @@ -27,7 +27,6 @@ import im.vector.app.core.services.BluetoothHeadsetReceiver import im.vector.app.core.services.WiredHeadsetStateReceiver import org.matrix.android.sdk.api.logger.LoggerTag import timber.log.Timber -import java.util.HashSet private val loggerTag = LoggerTag("API21AudioDeviceDetector", LoggerTag.VOIP) diff --git a/vector/src/main/java/im/vector/app/features/call/audio/API23AudioDeviceDetector.kt b/vector/src/main/java/im/vector/app/features/call/audio/API23AudioDeviceDetector.kt index fb17338fd1..7e12987a6b 100644 --- a/vector/src/main/java/im/vector/app/features/call/audio/API23AudioDeviceDetector.kt +++ b/vector/src/main/java/im/vector/app/features/call/audio/API23AudioDeviceDetector.kt @@ -21,7 +21,6 @@ import android.media.AudioManager import android.os.Build import androidx.annotation.RequiresApi import timber.log.Timber -import java.util.HashSet @RequiresApi(Build.VERSION_CODES.M) internal class API23AudioDeviceDetector(private val audioManager: AudioManager, diff --git a/vector/src/main/java/im/vector/app/features/call/audio/CallAudioManager.kt b/vector/src/main/java/im/vector/app/features/call/audio/CallAudioManager.kt index f4f56f9844..d4793640d3 100644 --- a/vector/src/main/java/im/vector/app/features/call/audio/CallAudioManager.kt +++ b/vector/src/main/java/im/vector/app/features/call/audio/CallAudioManager.kt @@ -25,7 +25,6 @@ import androidx.core.content.getSystemService import im.vector.app.R import org.matrix.android.sdk.api.extensions.orFalse import timber.log.Timber -import java.util.HashSet import java.util.concurrent.Executors class CallAudioManager(private val context: Context, val configChange: (() -> Unit)?) { diff --git a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt index f0b7b75afb..0ea380734d 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/JitsiCallViewModel.kt @@ -17,7 +17,6 @@ package im.vector.app.features.call.conference import androidx.lifecycle.asFlow -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.Fail import com.airbnb.mvrx.MavericksViewModelFactory import com.airbnb.mvrx.Success diff --git a/vector/src/main/java/im/vector/app/features/call/conference/JitsiService.kt b/vector/src/main/java/im/vector/app/features/call/conference/JitsiService.kt index b691296ba3..6fa65bdb7f 100644 --- a/vector/src/main/java/im/vector/app/features/call/conference/JitsiService.kt +++ b/vector/src/main/java/im/vector/app/features/call/conference/JitsiService.kt @@ -33,9 +33,9 @@ import org.matrix.android.sdk.api.raw.RawService import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.widgets.model.Widget import org.matrix.android.sdk.api.session.widgets.model.WidgetType +import org.matrix.android.sdk.api.util.MatrixJsonParser import org.matrix.android.sdk.api.util.appendParamToUrl import org.matrix.android.sdk.api.util.toMatrixItem -import org.matrix.android.sdk.internal.di.MoshiProvider import java.net.URL import java.util.UUID import javax.inject.Inject @@ -168,7 +168,7 @@ class JitsiService @Inject constructor( return tryOrNull { val response = session.getOkHttpClient().newCall(request).await() val json = response.body?.string() ?: return null - MoshiProvider.providesMoshi().adapter(JitsiWellKnown::class.java).fromJson(json)?.auth + MatrixJsonParser.getMoshi().adapter(JitsiWellKnown::class.java).fromJson(json)?.auth } } } diff --git a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt index b10353be13..81173568b5 100644 --- a/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt +++ b/vector/src/main/java/im/vector/app/features/call/transfer/CallTransferActivity.kt @@ -70,7 +70,6 @@ class CallTransferActivity : VectorBaseActivity<ActivityCallTransferBinding>() { }.attach() setupToolbar(views.callTransferToolbar) .allowBack() - views.callTransferToolbar.title = getString(R.string.call_transfer_title) setupConnectAction() } diff --git a/vector/src/main/java/im/vector/app/features/crypto/keys/KeysImporter.kt b/vector/src/main/java/im/vector/app/features/crypto/keys/KeysImporter.kt index 50c85c3e5f..9b1d29fa25 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keys/KeysImporter.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keys/KeysImporter.kt @@ -23,7 +23,7 @@ import im.vector.app.core.resources.openResource import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult +import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult import javax.inject.Inject class KeysImporter @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt index 8362a3566e..cf684680ba 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/restore/KeysBackupRestoreSharedViewModel.kt @@ -29,13 +29,15 @@ import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.listeners.StepProgressListener import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersionResult +import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey +import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult +import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.api.session.securestorage.KeyInfoResult -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult -import org.matrix.android.sdk.internal.crypto.keysbackup.util.computeRecoveryKey -import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult -import org.matrix.android.sdk.internal.util.awaitCallback +import org.matrix.android.sdk.api.util.awaitCallback +import org.matrix.android.sdk.api.util.fromBase64 import timber.log.Timber import javax.inject.Inject @@ -117,9 +119,9 @@ class KeysBackupRestoreSharedViewModel @Inject constructor( viewModelScope.launch(Dispatchers.IO) { try { - val version = awaitCallback<KeysVersionResult?> { + val version = awaitCallback<KeysBackupLastVersionResult> { keysBackup.getCurrentVersion(it) - } + }.toKeysVersionResult() if (version?.version == null) { loadingEvent.postValue(null) _keyVersionResultError.postValue(LiveEvent(stringProvider.getString(R.string.keys_backup_get_version_error, ""))) diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingViewState.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingViewState.kt index 438b502b42..7c1105277b 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingViewState.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingViewState.kt @@ -20,8 +20,8 @@ import com.airbnb.mvrx.Async import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.Uninitialized import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState -import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupVersionTrust +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersionResult data class KeysBackupSettingViewState(val keysBackupVersionTrust: Async<KeysBackupVersionTrust> = Uninitialized, val keysBackupState: KeysBackupState? = null, diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt index 3c922e6309..9bf8050939 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsRecyclerViewController.kt @@ -31,7 +31,7 @@ import im.vector.app.features.settings.VectorPreferences import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState -import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupVersionTrust import java.util.UUID import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt index d6d9e10669..ca6edf0941 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/settings/KeysBackupSettingsViewModel.kt @@ -33,7 +33,7 @@ import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupState import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupStateListener -import org.matrix.android.sdk.internal.crypto.keysbackup.model.KeysBackupVersionTrust +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupVersionTrust class KeysBackupSettingsViewModel @AssistedInject constructor(@Assisted initialState: KeysBackupSettingViewState, session: Session diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupSharedViewModel.kt index 1141886689..34aa7ba0ee 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysbackup/setup/KeysBackupSetupSharedViewModel.kt @@ -26,10 +26,11 @@ import im.vector.app.core.utils.LiveEvent import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupService -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersion +import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreationInfo +import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult import timber.log.Timber import javax.inject.Inject @@ -150,9 +151,9 @@ class KeysBackupSetupSharedViewModel @Inject constructor() : ViewModel() { creatingBackupError.value = null - keysBackup.getCurrentVersion(object : MatrixCallback<KeysVersionResult?> { - override fun onSuccess(data: KeysVersionResult?) { - if (data?.version.isNullOrBlank() || forceOverride) { + keysBackup.getCurrentVersion(object : MatrixCallback<KeysBackupLastVersionResult> { + override fun onSuccess(data: KeysBackupLastVersionResult) { + if (data.toKeysVersionResult()?.version.isNullOrBlank() || forceOverride) { processOnCreate() } else { loadingStatus.value = null diff --git a/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt b/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt index 85250a94ce..0fbb18e63c 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/keysrequest/KeyRequestHandler.kt @@ -24,18 +24,18 @@ import im.vector.app.features.popup.DefaultVectorAlert import im.vector.app.features.popup.PopupAlertManager import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel import org.matrix.android.sdk.api.session.crypto.keyshare.GossipingRequestListener +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.IncomingRequestCancellation +import org.matrix.android.sdk.api.session.crypto.model.IncomingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.IncomingSecretShareRequest +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.crypto.verification.SasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState -import org.matrix.android.sdk.internal.crypto.IncomingRequestCancellation -import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest -import org.matrix.android.sdk.internal.crypto.IncomingSecretShareRequest -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import timber.log.Timber import javax.inject.Inject import javax.inject.Singleton diff --git a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt index d324a52242..51d8b3a8d5 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/quads/SharedSecureStorageViewModel.kt @@ -41,8 +41,8 @@ import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.securestorage.IntegrityResult import org.matrix.android.sdk.api.session.securestorage.KeyInfoResult import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec +import org.matrix.android.sdk.api.util.toBase64NoPadding import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding import timber.log.Timber import java.io.ByteArrayOutputStream diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BackupToQuadSMigrationTask.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BackupToQuadSMigrationTask.kt index 74bab9b0b6..1767a9444d 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BackupToQuadSMigrationTask.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BackupToQuadSMigrationTask.kt @@ -24,15 +24,14 @@ import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.listeners.ProgressListener import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME +import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey +import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey import org.matrix.android.sdk.api.session.securestorage.EmptyKeySigner import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo -import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding -import org.matrix.android.sdk.internal.crypto.keysbackup.deriveKey -import org.matrix.android.sdk.internal.crypto.keysbackup.util.computeRecoveryKey -import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey -import org.matrix.android.sdk.internal.util.awaitCallback +import org.matrix.android.sdk.api.util.awaitCallback +import org.matrix.android.sdk.api.util.toBase64NoPadding import timber.log.Timber import java.util.UUID import javax.inject.Inject @@ -72,14 +71,18 @@ class BackupToQuadSMigrationTask @Inject constructor( extractCurveKeyFromRecoveryKey(params.recoveryKey) } else if (!params.passphrase.isNullOrEmpty() && version.getAuthDataAsMegolmBackupAuthData()?.privateKeySalt != null) { version.getAuthDataAsMegolmBackupAuthData()?.let { authData -> - deriveKey(params.passphrase, authData.privateKeySalt!!, authData.privateKeyIterations!!, object : ProgressListener { - override fun onProgress(progress: Int, total: Int) { - params.progressListener?.onProgress(WaitingViewData( - stringProvider.getString(R.string.bootstrap_progress_checking_backup_with_info, - "$progress/$total") - )) - } - }) + keysBackupService.computePrivateKey( + params.passphrase, + authData.privateKeySalt!!, + authData.privateKeyIterations!!, + object : ProgressListener { + override fun onProgress(progress: Int, total: Int) { + params.progressListener?.onProgress(WaitingViewData( + stringProvider.getString(R.string.bootstrap_progress_checking_backup_with_info, + "$progress/$total") + )) + } + }) } } else null) ?: return Result.IllegalParams diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt index cc863346aa..f65999b945 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapCrossSigningTask.kt @@ -28,16 +28,17 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_S import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersion +import org.matrix.android.sdk.api.session.crypto.keysbackup.MegolmBackupCreationInfo +import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey +import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult import org.matrix.android.sdk.api.session.securestorage.EmptyKeySigner import org.matrix.android.sdk.api.session.securestorage.SharedSecretStorageService import org.matrix.android.sdk.api.session.securestorage.SsssKeyCreationInfo import org.matrix.android.sdk.api.session.securestorage.SsssKeySpec -import org.matrix.android.sdk.internal.crypto.crosssigning.toBase64NoPadding -import org.matrix.android.sdk.internal.crypto.keysbackup.model.MegolmBackupCreationInfo -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersion -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult -import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey -import org.matrix.android.sdk.internal.util.awaitCallback +import org.matrix.android.sdk.api.util.awaitCallback +import org.matrix.android.sdk.api.util.toBase64NoPadding import timber.log.Timber import java.util.UUID import javax.inject.Inject @@ -221,10 +222,9 @@ class BootstrapCrossSigningTask @Inject constructor( Timber.d("## BootstrapCrossSigningTask: Creating 4S - Checking megolm backup") // First ensure that in sync - var serverVersion = awaitCallback<KeysVersionResult?> { + var serverVersion = awaitCallback<KeysBackupLastVersionResult> { session.cryptoService().keysBackupService().getCurrentVersion(it) - } - + }.toKeysVersionResult() val knownMegolmSecret = session.cryptoService().keysBackupService().getKeyBackupRecoveryKeyInfo() val isMegolmBackupSecretKnown = knownMegolmSecret != null && knownMegolmSecret.version == serverVersion?.version val shouldCreateKeyBackup = serverVersion == null || @@ -236,9 +236,9 @@ class BootstrapCrossSigningTask @Inject constructor( awaitCallback<Unit> { session.cryptoService().keysBackupService().deleteBackup(serverVersion!!.version, it) } - serverVersion = awaitCallback { + serverVersion = awaitCallback<KeysBackupLastVersionResult> { session.cryptoService().keysBackupService().getCurrentVersion(it) - } + }.toKeysVersionResult() } Timber.d("## BootstrapCrossSigningTask: Creating 4S - Create megolm backup") diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapMigrateBackupFragment.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapMigrateBackupFragment.kt index 429d51857c..2c0ccec9fb 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapMigrateBackupFragment.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapMigrateBackupFragment.kt @@ -42,7 +42,7 @@ import im.vector.lib.core.utils.flow.throttleFirst import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.internal.crypto.keysbackup.util.isValidRecoveryKey +import org.matrix.android.sdk.api.session.crypto.keysbackup.isValidRecoveryKey import reactivecircus.flowbinding.android.widget.editorActionEvents import reactivecircus.flowbinding.android.widget.textChanges import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt index 8b8a8faaef..1b69b3a919 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/recover/BootstrapSharedViewModel.kt @@ -43,12 +43,14 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysVersionResult +import org.matrix.android.sdk.api.session.crypto.keysbackup.extractCurveKeyFromRecoveryKey +import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult import org.matrix.android.sdk.api.session.securestorage.RawBytesKeySpec -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult -import org.matrix.android.sdk.internal.crypto.keysbackup.util.extractCurveKeyFromRecoveryKey -import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth -import org.matrix.android.sdk.internal.util.awaitCallback +import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth +import org.matrix.android.sdk.api.util.awaitCallback +import org.matrix.android.sdk.api.util.fromBase64 import java.io.OutputStream import kotlin.coroutines.Continuation import kotlin.coroutines.resume @@ -103,9 +105,9 @@ class BootstrapSharedViewModel @AssistedInject constructor( // We need to check if there is an existing backup viewModelScope.launch(Dispatchers.IO) { - val version = awaitCallback<KeysVersionResult?> { + val version = awaitCallback<KeysBackupLastVersionResult> { session.cryptoService().keysBackupService().getCurrentVersion(it) - } + }.toKeysVersionResult() if (version == null) { // we just resume plain bootstrap doesKeyBackupExist = false diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt index f48279a86e..18a1363d71 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheet.kt @@ -48,12 +48,12 @@ import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.settings.VectorSettingsActivity import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState import timber.log.Timber diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt index 2495ae4ea5..b389a831da 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/VerificationBottomSheetViewModel.kt @@ -38,6 +38,11 @@ import org.matrix.android.sdk.api.session.crypto.crosssigning.KEYBACKUP_SECRET_S import org.matrix.android.sdk.api.session.crypto.crosssigning.MASTER_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.SELF_SIGNING_KEY_SSSS_NAME import org.matrix.android.sdk.api.session.crypto.crosssigning.USER_SIGNING_KEY_SSSS_NAME +import org.matrix.android.sdk.api.session.crypto.crosssigning.isVerified +import org.matrix.android.sdk.api.session.crypto.keysbackup.KeysBackupLastVersionResult +import org.matrix.android.sdk.api.session.crypto.keysbackup.computeRecoveryKey +import org.matrix.android.sdk.api.session.crypto.keysbackup.toKeysVersionResult +import org.matrix.android.sdk.api.session.crypto.model.ImportRoomKeysResult import org.matrix.android.sdk.api.session.crypto.verification.CancelCode import org.matrix.android.sdk.api.session.crypto.verification.IncomingSasVerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.PendingVerificationRequest @@ -49,13 +54,9 @@ import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransa import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState import org.matrix.android.sdk.api.session.events.model.LocalEcho import org.matrix.android.sdk.api.util.MatrixItem +import org.matrix.android.sdk.api.util.awaitCallback +import org.matrix.android.sdk.api.util.fromBase64 import org.matrix.android.sdk.api.util.toMatrixItem -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified -import org.matrix.android.sdk.internal.crypto.keysbackup.model.rest.KeysVersionResult -import org.matrix.android.sdk.internal.crypto.keysbackup.util.computeRecoveryKey -import org.matrix.android.sdk.internal.crypto.model.ImportRoomKeysResult -import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber data class VerificationBottomSheetViewState( @@ -426,9 +427,9 @@ class VerificationBottomSheetViewModel @AssistedInject constructor( Timber.v("## Keybackup secret not restored from SSSS") } - val version = awaitCallback<KeysVersionResult?> { + val version = awaitCallback<KeysBackupLastVersionResult> { session.cryptoService().keysBackupService().getCurrentVersion(it) - } ?: return@launch + }.toKeysVersionResult() ?: return@launch awaitCallback<ImportRoomKeysResult> { session.cryptoService().keysBackupService().restoreKeysWithRecoveryKey( diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionController.kt index 1d6dfbd947..ee77444b2e 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/conclusion/VerificationConclusionController.kt @@ -26,7 +26,7 @@ import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationB import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationNoticeItem import im.vector.app.features.html.EventHtmlRenderer import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import javax.inject.Inject class VerificationConclusionController @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/epoxy/BottomSheetVerificationBigImageItem.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/epoxy/BottomSheetVerificationBigImageItem.kt index b15f857c3a..adf3e8f7e5 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/epoxy/BottomSheetVerificationBigImageItem.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/epoxy/BottomSheetVerificationBigImageItem.kt @@ -22,7 +22,7 @@ import im.vector.app.R import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyModel import im.vector.app.core.ui.views.ShieldImageView -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel /** * A action for bottom sheet. diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQRWaitingController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQRWaitingController.kt index 8de5f94ec9..1ae0da603a 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQRWaitingController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQRWaitingController.kt @@ -24,7 +24,7 @@ import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationB import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationNoticeItem import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationWaitingItem import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import javax.inject.Inject class VerificationQRWaitingController @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt index 38f29622d0..71d64b99bc 100644 --- a/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt +++ b/vector/src/main/java/im/vector/app/features/crypto/verification/qrconfirmation/VerificationQrScannedByOtherController.kt @@ -27,7 +27,7 @@ import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationB import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationNoticeItem import im.vector.app.features.displayname.getBestName import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import javax.inject.Inject class VerificationQrScannedByOtherController @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt index c3524e2cdf..c13ef2f81c 100644 --- a/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/devtools/RoomDevToolViewModel.kt @@ -38,8 +38,8 @@ import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.api.util.MatrixJsonParser import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.internal.di.MoshiProvider class RoomDevToolViewModel @AssistedInject constructor( @Assisted val initialState: RoomDevToolViewState, @@ -75,7 +75,7 @@ class RoomDevToolViewModel @AssistedInject constructor( } } is RoomDevToolAction.ShowStateEvent -> { - val jsonString = MoshiProvider.providesMoshi() + val jsonString = MatrixJsonParser.getMoshi() .adapter(Event::class.java) .toJson(action.event) @@ -168,7 +168,7 @@ class RoomDevToolViewModel @AssistedInject constructor( val room = session.getRoom(initialState.roomId) ?: throw IllegalArgumentException(stringProvider.getString(R.string.room_error_not_found)) - val adapter = MoshiProvider.providesMoshi() + val adapter = MatrixJsonParser.getMoshi() .adapter<JsonDict>(Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)) val json = adapter.fromJson(state.editedContent ?: "") ?: throw IllegalArgumentException(stringProvider.getString(R.string.dev_tools_error_no_content)) @@ -202,7 +202,7 @@ class RoomDevToolViewModel @AssistedInject constructor( val room = session.getRoom(initialState.roomId) ?: throw IllegalArgumentException(stringProvider.getString(R.string.room_error_not_found)) - val adapter = MoshiProvider.providesMoshi() + val adapter = MatrixJsonParser.getMoshi() .adapter<JsonDict>(Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)) val json = adapter.fromJson(state.sendEventDraft?.content ?: "") ?: throw IllegalArgumentException(stringProvider.getString(R.string.dev_tools_error_no_content)) diff --git a/vector/src/main/java/im/vector/app/features/discovery/Extensions.kt b/vector/src/main/java/im/vector/app/features/discovery/Extensions.kt index 24d675695b..904b152661 100644 --- a/vector/src/main/java/im/vector/app/features/discovery/Extensions.kt +++ b/vector/src/main/java/im/vector/app/features/discovery/Extensions.kt @@ -18,8 +18,8 @@ package im.vector.app.features.discovery import im.vector.app.core.utils.ensureProtocol import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.terms.TermsResponse import org.matrix.android.sdk.api.session.terms.TermsService -import org.matrix.android.sdk.internal.session.terms.TermsResponse suspend fun Session.fetchIdentityServerWithTerms(userLanguage: String): ServerAndPolicies? { return identityService().getCurrentIdentityServerUrl() diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt index bcd3b5dd57..38c7a19052 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivity.kt @@ -84,9 +84,9 @@ import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.permalinks.PermalinkService +import org.matrix.android.sdk.api.session.sync.InitialSyncStrategy +import org.matrix.android.sdk.api.session.sync.initialSyncStrategy import org.matrix.android.sdk.api.util.MatrixItem -import org.matrix.android.sdk.internal.session.sync.InitialSyncStrategy -import org.matrix.android.sdk.internal.session.sync.initialSyncStrategy import timber.log.Timber import javax.inject.Inject @@ -367,7 +367,7 @@ class HomeActivity : private fun renderState(state: HomeActivityViewState) { when (val status = state.syncStatusServiceStatus) { - is SyncStatusService.Status.Progressing -> { + is SyncStatusService.Status.InitialSyncProgressing -> { val initSyncStepStr = initSyncStepFormatter.format(status.initSyncStep) Timber.v("$initSyncStepStr ${status.percentProgress}") views.waitingView.root.setOnClickListener { @@ -597,7 +597,7 @@ class HomeActivity : } override fun spaceInviteBottomSheetOnAccept(spaceId: String) { - navigator.switchToSpace(this, spaceId, Navigator.PostSwitchSpaceAction.None) + navigator.switchToSpace(this, spaceId, Navigator.PostSwitchSpaceAction.OpenRoomList) } override fun spaceInviteBottomSheetOnDecline(spaceId: String) { @@ -630,6 +630,6 @@ class HomeActivity : } override fun mxToBottomSheetSwitchToSpace(spaceId: String) { - navigator.switchToSpace(this, spaceId, Navigator.PostSwitchSpaceAction.None) + navigator.switchToSpace(this, spaceId, Navigator.PostSwitchSpaceAction.OpenRoomList) } } diff --git a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt index 87de0a32e3..c8b0fa024e 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeActivityViewModel.kt @@ -43,15 +43,15 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.pushrules.RuleIds +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage +import org.matrix.android.sdk.api.util.awaitCallback import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.MXUsersDevicesMap -import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage -import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber import kotlin.coroutines.Continuation import kotlin.coroutines.resume @@ -179,11 +179,11 @@ class HomeActivityViewModel @AssistedInject constructor( .asFlow() .onEach { status -> when (status) { - is SyncStatusService.Status.Progressing -> { + is SyncStatusService.Status.InitialSyncProgressing -> { // Schedule a check of the bootstrap when the init sync will be finished checkBootstrap = true } - is SyncStatusService.Status.Idle -> { + is SyncStatusService.Status.Idle -> { if (checkBootstrap) { checkBootstrap = false maybeBootstrapCrossSigningAfterInitialSync() diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt index b1c9b3bba5..7e73abff1a 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailFragment.kt @@ -63,9 +63,9 @@ import im.vector.app.features.settings.VectorSettingsActivity.Companion.EXTRA_DI import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.workers.signout.BannerState import im.vector.app.features.workers.signout.ServerBackupStatusViewModel +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo import org.matrix.android.sdk.api.session.group.model.GroupSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import timber.log.Timber import javax.inject.Inject import kotlin.math.abs diff --git a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt index 0700ff4d5f..8f7c236521 100644 --- a/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/HomeDetailViewModel.kt @@ -51,6 +51,7 @@ import org.matrix.android.sdk.api.query.ActiveSpaceFilter import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.query.RoomCategoryFilter import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.NewSessionListener import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.initsync.SyncStatusService import org.matrix.android.sdk.api.session.room.Room @@ -62,7 +63,6 @@ import org.matrix.android.sdk.api.session.space.model.SpaceOrderContent import org.matrix.android.sdk.api.session.space.model.TopLevelSpaceComparator import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.internal.crypto.NewSessionListener import timber.log.Timber /** diff --git a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt index 8a36a4c19e..08b528f25a 100644 --- a/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/UnknownDeviceDetectorSharedViewModel.kt @@ -38,10 +38,10 @@ import kotlinx.coroutines.flow.sample import org.matrix.android.sdk.api.NoOpMatrixCallback import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo import timber.log.Timber data class UnknownDevicesState( diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt index d10b363519..f6ea8b76ef 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailAction.kt @@ -111,4 +111,7 @@ sealed class RoomDetailAction : VectorViewModelAction { // Poll data class EndPoll(val eventId: String) : RoomDetailAction() + + // Live Location + object StopLiveLocationSharing : RoomDetailAction() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt index aa4ee825dc..5784e6e264 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailActivity.kt @@ -38,7 +38,7 @@ import im.vector.app.databinding.ActivityRoomDetailBinding import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.home.room.breadcrumbs.BreadcrumbsFragment import im.vector.app.features.home.room.detail.arguments.TimelineArgs -import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlaybackTracker +import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker import im.vector.app.features.matrixto.MatrixToBottomSheet import im.vector.app.features.navigation.Navigator import im.vector.app.features.room.RequireActiveMembershipAction @@ -75,7 +75,7 @@ class RoomDetailActivity : } private var lastKnownPlayingOrRecordingState: Boolean? = null - private val playbackActivityListener = VoiceMessagePlaybackTracker.ActivityListener { isPlayingOrRecording -> + private val playbackActivityListener = AudioMessagePlaybackTracker.ActivityListener { isPlayingOrRecording -> if (lastKnownPlayingOrRecordingState == isPlayingOrRecording) return@ActivityListener when (isPlayingOrRecording) { true -> keepScreenOn() @@ -86,7 +86,7 @@ class RoomDetailActivity : override fun getCoordinatorLayout() = views.coordinatorLayout - @Inject lateinit var playbackTracker: VoiceMessagePlaybackTracker + @Inject lateinit var playbackTracker: AudioMessagePlaybackTracker private lateinit var sharedActionViewModel: RoomDetailSharedActionViewModel private val requireActiveMembershipViewModel: RequireActiveMembershipViewModel by viewModel() @@ -152,7 +152,7 @@ class RoomDetailActivity : override fun onDestroy() { supportFragmentManager.unregisterFragmentLifecycleCallbacks(fragmentLifecycleCallbacks) views.drawerLayout.removeDrawerListener(drawerListener) - playbackTracker.unTrackActivity(playbackActivityListener) + playbackTracker.untrackActivity(playbackActivityListener) super.onDestroy() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt index 23747c7223..53e8901c72 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/RoomDetailViewEvents.kt @@ -20,10 +20,10 @@ import android.net.Uri import android.view.View import im.vector.app.core.platform.VectorViewEvents import im.vector.app.features.call.webrtc.WebRtcCall +import org.matrix.android.sdk.api.session.events.model.content.WithHeldCode import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.widgets.model.Widget import org.matrix.android.sdk.api.util.MatrixItem -import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode import java.io.File /** diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt index 5800fb9e9c..5e4db65aec 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineFragment.kt @@ -124,6 +124,8 @@ import im.vector.app.core.utils.startInstallFromSourceIntent import im.vector.app.core.utils.toast import im.vector.app.databinding.DialogReportContentBinding import im.vector.app.databinding.FragmentTimelineBinding +import im.vector.app.features.MainActivity +import im.vector.app.features.MainActivityArgs import im.vector.app.features.analytics.extensions.toAnalyticsInteraction import im.vector.app.features.analytics.plan.Interaction import im.vector.app.features.analytics.plan.MobileScreen @@ -141,6 +143,7 @@ import im.vector.app.features.call.conference.ConferenceEventObserver import im.vector.app.features.call.conference.JitsiCallViewModel import im.vector.app.features.call.webrtc.WebRtcCallManager import im.vector.app.features.command.Command +import im.vector.app.features.command.ParsedCommand import im.vector.app.features.crypto.keysbackup.restore.KeysBackupRestoreActivity import im.vector.app.features.crypto.verification.VerificationBottomSheet import im.vector.app.features.home.AvatarRenderer @@ -161,10 +164,11 @@ import im.vector.app.features.home.room.detail.timeline.action.EventSharedAction import im.vector.app.features.home.room.detail.timeline.action.MessageActionsBottomSheet import im.vector.app.features.home.room.detail.timeline.action.MessageSharedActionViewModel import im.vector.app.features.home.room.detail.timeline.edithistory.ViewEditHistoryBottomSheet +import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorProvider -import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlaybackTracker import im.vector.app.features.home.room.detail.timeline.image.buildImageContentRendererData import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem +import im.vector.app.features.home.room.detail.timeline.item.MessageAudioItem import im.vector.app.features.home.room.detail.timeline.item.MessageFileItem import im.vector.app.features.home.room.detail.timeline.item.MessageImageVideoItem import im.vector.app.features.home.room.detail.timeline.item.MessageInformationData @@ -216,10 +220,11 @@ import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import org.billcarsonfr.jsonviewer.JSonViewerDialog import org.commonmark.parser.Parser -import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.content.ContentAttachmentData import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent +import org.matrix.android.sdk.api.session.events.model.content.WithHeldCode import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomSummary @@ -243,8 +248,6 @@ import org.matrix.android.sdk.api.session.widgets.model.WidgetType import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.MimeTypes import org.matrix.android.sdk.api.util.toMatrixItem -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent -import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode import reactivecircus.flowbinding.android.view.focusChanges import reactivecircus.flowbinding.android.widget.textChanges import timber.log.Timber @@ -272,10 +275,9 @@ class TimelineFragment @Inject constructor( private val roomDetailPendingActionStore: RoomDetailPendingActionStore, private val pillsPostProcessorFactory: PillsPostProcessor.Factory, private val callManager: WebRtcCallManager, - private val voiceMessagePlaybackTracker: VoiceMessagePlaybackTracker, private val typingHelper: TypingHelper, - private val clock: Clock, - private val matrixConfiguration: MatrixConfiguration + private val audioMessagePlaybackTracker: AudioMessagePlaybackTracker, + private val clock: Clock ) : VectorBaseFragment<FragmentTimelineBinding>(), TimelineEventController.Callback, @@ -399,6 +401,7 @@ class TimelineFragment @Inject constructor( setupEmojiButton() setupRemoveJitsiWidgetView() setupVoiceMessageView() + setupLiveLocationIndicator() views.scRoomDebugView.isVisible = DbgUtil.isDbgEnabled(DbgUtil.DBG_SHOW_READ_TRACKING) @@ -453,6 +456,7 @@ class TimelineFragment @Inject constructor( messageComposerViewModel.observeViewEvents { when (it) { is MessageComposerViewEvents.JoinRoomCommandSuccess -> handleJoinedToAnotherRoom(it) + is MessageComposerViewEvents.SlashCommandConfirmationRequest -> handleSlashCommandConfirmationRequest(it) is MessageComposerViewEvents.SendMessageResult -> renderSendMessageResult(it) is MessageComposerViewEvents.ShowMessage -> showSnackWithMessage(it.message) is MessageComposerViewEvents.ShowRoomUpgradeDialog -> handleShowRoomUpgradeDialog(it) @@ -512,6 +516,25 @@ class TimelineFragment @Inject constructor( } } + private fun handleSlashCommandConfirmationRequest(action: MessageComposerViewEvents.SlashCommandConfirmationRequest) { + when (action.parsedCommand) { + is ParsedCommand.UnignoreUser -> promptUnignoreUser(action.parsedCommand) + else -> TODO("Add case for ${action.parsedCommand.javaClass.simpleName}") + } + lockSendButton = false + } + + private fun promptUnignoreUser(command: ParsedCommand.UnignoreUser) { + MaterialAlertDialogBuilder(requireActivity()) + .setTitle(R.string.room_participants_action_unignore_title) + .setMessage(getString(R.string.settings_unignore_user, command.userId)) + .setPositiveButton(R.string.unignore) { _, _ -> + messageComposerViewModel.handle(MessageComposerAction.SlashCommandConfirmed(command)) + } + .setNegativeButton(R.string.action_cancel, null) + .show() + } + private fun renderVoiceMessageMode(content: String) { ContentAttachmentData.fromJsonString(content)?.let { audioAttachmentData -> views.voiceMessageRecorderView.isVisible = true @@ -764,7 +787,7 @@ class TimelineFragment @Inject constructor( } private fun setupVoiceMessageView() { - voiceMessagePlaybackTracker.track(VoiceMessagePlaybackTracker.RECORDING_ID, views.voiceMessageRecorderView) + audioMessagePlaybackTracker.track(AudioMessagePlaybackTracker.RECORDING_ID, views.voiceMessageRecorderView) views.voiceMessageRecorderView.callback = object : VoiceMessageRecorderView.Callback { override fun onVoiceRecordingStarted() { @@ -821,13 +844,13 @@ class TimelineFragment @Inject constructor( override fun onVoiceWaveformTouchedUp(percentage: Float, duration: Int) { messageComposerViewModel.handle( - MessageComposerAction.VoiceWaveformTouchedUp(VoiceMessagePlaybackTracker.RECORDING_ID, duration, percentage) + MessageComposerAction.VoiceWaveformTouchedUp(AudioMessagePlaybackTracker.RECORDING_ID, duration, percentage) ) } override fun onVoiceWaveformMoved(percentage: Float, duration: Int) { messageComposerViewModel.handle( - MessageComposerAction.VoiceWaveformTouchedUp(VoiceMessagePlaybackTracker.RECORDING_ID, duration, percentage) + MessageComposerAction.VoiceWaveformTouchedUp(AudioMessagePlaybackTracker.RECORDING_ID, duration, percentage) ) } @@ -838,6 +861,12 @@ class TimelineFragment @Inject constructor( } } + private fun setupLiveLocationIndicator() { + views.locationLiveStatusIndicator.stopButton.debouncedClicks { + timelineViewModel.handle(RoomDetailAction.StopLiveLocationSharing) + } + } + private fun joinJitsiRoom(jitsiWidget: Widget, enableVideo: Boolean) { navigator.openRoomWidget(requireContext(), timelineArgs.roomId, jitsiWidget, mapOf(JitsiCallViewModel.ENABLE_VIDEO_OPTION to enableVideo)) } @@ -935,6 +964,7 @@ class TimelineFragment @Inject constructor( } override fun onDestroyView() { + audioMessagePlaybackTracker.makeAllPlaybacksIdle() lazyLoadedViews.unBind() timelineEventController.callback = null timelineEventController.removeModelBuildListener(modelBuildListener) @@ -1284,13 +1314,10 @@ class TimelineFragment @Inject constructor( } val messageContent: MessageContent? = event.getLastMessageContent() - val nonFormattedBody = if (messageContent is MessageAudioContent && messageContent.voiceMessageIndicator != null) { - val formattedDuration = DateUtils.formatElapsedTime(((messageContent.audioInfo?.duration ?: 0) / 1000).toLong()) - getString(R.string.voice_message_reply_content, formattedDuration) - } else if (messageContent is MessagePollContent) { - messageContent.getBestPollCreationInfo()?.question?.getBestQuestion() - } else { - messageContent?.body ?: "" + val nonFormattedBody = when (messageContent) { + is MessageAudioContent -> getAudioContentBodyText(messageContent) + is MessagePollContent -> messageContent.getBestPollCreationInfo()?.question?.getBestQuestion() + else -> messageContent?.body.orEmpty() } var formattedBody: CharSequence? = null if (messageContent is MessageTextContent && messageContent.format == MessageFormat.FORMAT_MATRIX_HTML) { @@ -1329,6 +1356,15 @@ class TimelineFragment @Inject constructor( focusComposerAndShowKeyboard() } + private fun getAudioContentBodyText(messageContent: MessageAudioContent): String { + val formattedDuration = DateUtils.formatElapsedTime(((messageContent.audioInfo?.duration ?: 0) / 1000).toLong()) + return if (messageContent.voiceMessageIndicator != null) { + getString(R.string.voice_message_reply_content, formattedDuration) + } else { + getString(R.string.audio_message_reply_content, messageContent.body, formattedDuration) + } + } + override fun onResume() { super.onResume() notificationDrawerManager.setCurrentRoom(timelineArgs.roomId) @@ -1353,7 +1389,7 @@ class TimelineFragment @Inject constructor( override fun onPause() { super.onPause() notificationDrawerManager.setCurrentRoom(null) - voiceMessagePlaybackTracker.unTrack(VoiceMessagePlaybackTracker.RECORDING_ID) + audioMessagePlaybackTracker.pauseAllPlaybacks() if (withState(messageComposerViewModel) { it.isVoiceRecording } && requireActivity().isChangingConfigurations) { // we're rotating, maintain any active recordings @@ -1497,6 +1533,7 @@ class TimelineFragment @Inject constructor( } return when (model) { is MessageFileItem, + is MessageAudioItem, is MessageVoiceItem, is MessageImageVideoItem, is MessageTextItem -> { @@ -1766,7 +1803,7 @@ class TimelineFragment @Inject constructor( views.includeRoomToolbar.roomToolbarContentView.isClickable = roomSummary.membership == Membership.JOIN views.includeRoomToolbar.roomToolbarTitleView.text = roomSummary.displayName avatarRenderer.render(roomSummary.toMatrixItem(), views.includeRoomToolbar.roomToolbarAvatarImageView) - val showPresence = roomSummary.isDirect && matrixConfiguration.presenceSyncEnabled + val showPresence = roomSummary.isDirect views.includeRoomToolbar.roomToolbarPresenceImageView.render(showPresence, roomSummary.directUserPresence) //val shieldView = if (showPresence) views.includeRoomToolbar.roomToolbarTitleShield else views.includeRoomToolbar.roomToolbarAvatarShield val shieldView = views.includeRoomToolbar.roomToolbarDecorationImageView @@ -1812,9 +1849,7 @@ class TimelineFragment @Inject constructor( displayCommandError(getString(R.string.unrecognized_command, sendMessageResult.command)) } is MessageComposerViewEvents.SlashCommandResultOk -> { - dismissLoadingDialog() - views.composerLayout.setTextIfDifferent("") - sendMessageResult.messageRes?.let { showSnackWithMessage(getString(it)) } + handleSlashCommandResultOk(sendMessageResult.parsedCommand) } is MessageComposerViewEvents.SlashCommandResultError -> { dismissLoadingDialog() @@ -1831,6 +1866,21 @@ class TimelineFragment @Inject constructor( lockSendButton = false } + private fun handleSlashCommandResultOk(parsedCommand: ParsedCommand) { + dismissLoadingDialog() + views.composerLayout.setTextIfDifferent("") + when (parsedCommand) { + is ParsedCommand.SetMarkdown -> { + showSnackWithMessage(getString(if (parsedCommand.enable) R.string.markdown_has_been_enabled else R.string.markdown_has_been_disabled)) + } + is ParsedCommand.UnignoreUser -> { + // A user has been un-ignored, perform a initial sync + MainActivity.restartApp(requireActivity(), MainActivityArgs(clearCache = true)) + } + else -> Unit + } + } + private fun displayCommandError(message: String) { MaterialAlertDialogBuilder(requireActivity()) .setTitle(R.string.command_error) @@ -2229,6 +2279,10 @@ class TimelineFragment @Inject constructor( messageComposerViewModel.handle(MessageComposerAction.VoiceWaveformMovedTo(eventId, duration, percentage)) } + override fun onAudioSeekBarMovedTo(eventId: String, duration: Int, percentage: Float) { + messageComposerViewModel.handle(MessageComposerAction.AudioSeekBarMovedTo(eventId, duration, percentage)) + } + private fun onShareActionClicked(action: EventSharedAction.Share) { when (action.messageContent) { is MessageTextContent -> shareText(requireContext(), action.messageContent.body) @@ -2543,23 +2597,23 @@ class TimelineFragment @Inject constructor( } private fun displayThreadsBetaOptInDialog() { - activity?.let { - MaterialAlertDialogBuilder(it) - .setTitle(R.string.threads_beta_enable_notice_title) - .setMessage(threadsManager.getBetaEnableThreadsMessage()) - .setCancelable(true) - .setNegativeButton(R.string.action_not_now) { _, _ -> } - .setPositiveButton(R.string.action_try_it_out) { _, _ -> - threadsManager.enableThreadsAndRestart(it) - } - .show() - ?.findViewById<TextView>(android.R.id.message) - ?.apply { - linksClickable = true - movementMethod = LinkMovementMethod.getInstance() - } - } + activity?.let { + MaterialAlertDialogBuilder(it) + .setTitle(R.string.threads_beta_enable_notice_title) + .setMessage(threadsManager.getBetaEnableThreadsMessage()) + .setCancelable(true) + .setNegativeButton(R.string.action_not_now) { _, _ -> } + .setPositiveButton(R.string.action_try_it_out) { _, _ -> + threadsManager.enableThreadsAndRestart(it) + } + .show() + ?.findViewById<TextView>(android.R.id.message) + ?.apply { + linksClickable = true + movementMethod = LinkMovementMethod.getInstance() + } } + } /** * Navigate to Threads list for the current room diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt index 7eded73fb1..8707353855 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/TimelineViewModel.kt @@ -83,6 +83,7 @@ import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.LocalEcho import org.matrix.android.sdk.api.session.events.model.RelationType +import org.matrix.android.sdk.api.session.events.model.content.WithHeldCode import org.matrix.android.sdk.api.session.events.model.isAttachmentMessage import org.matrix.android.sdk.api.session.events.model.isTextMessage import org.matrix.android.sdk.api.session.events.model.toContent @@ -107,7 +108,6 @@ import org.matrix.android.sdk.api.session.widgets.model.WidgetType import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.flow.flow import org.matrix.android.sdk.flow.unwrap -import org.matrix.android.sdk.internal.crypto.model.event.WithHeldCode import timber.log.Timber import java.util.concurrent.atomic.AtomicBoolean @@ -475,6 +475,7 @@ class TimelineViewModel @AssistedInject constructor( _viewEvents.post(RoomDetailViewEvents.OpenRoom(action.replacementRoomId, closeCurrentRoom = true)) } is RoomDetailAction.EndPoll -> handleEndPoll(action.eventId) + RoomDetailAction.StopLiveLocationSharing -> handleStopLiveLocationSharing() } } @@ -1134,6 +1135,10 @@ class TimelineViewModel @AssistedInject constructor( } } + private fun handleStopLiveLocationSharing() { + locationSharingServiceConnection.stopLiveLocationSharing(room.roomId) + } + private fun observeRoomSummary() { room.flow().liveRoomSummary() .unwrap() @@ -1152,7 +1157,8 @@ class TimelineViewModel @AssistedInject constructor( computeUnreadState(timelineEvents, roomSummary) } // We don't want live update of unread so we skip when we already had a HasUnread or HasNoUnread - // However, we want to update an existing HasUnread, as we might get additional information during loading of events. + // However, we want to update an existing HasUnread, if the readMarkerId hasn't changed, + // as we might be loading new events to fill gaps in the timeline. .distinctUntilChanged { previous, current -> when { previous is UnreadState.Unknown || previous is UnreadState.ReadMarkerNotLoaded -> false diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt similarity index 88% rename from vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt rename to vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt index c5d8b7a5c1..f4cab3305d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/VoiceMessageHelper.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/AudioMessageHelper.kt @@ -21,7 +21,7 @@ import android.media.AudioAttributes import android.media.MediaPlayer import androidx.core.content.FileProvider import im.vector.app.BuildConfig -import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlaybackTracker +import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker import im.vector.app.features.voice.VoiceFailure import im.vector.app.features.voice.VoiceRecorder import im.vector.app.features.voice.VoiceRecorderProvider @@ -40,12 +40,13 @@ import javax.inject.Inject /** * Helper class to record audio for voice messages. */ -class VoiceMessageHelper @Inject constructor( +class AudioMessageHelper @Inject constructor( private val context: Context, - private val playbackTracker: VoiceMessagePlaybackTracker, + private val playbackTracker: AudioMessagePlaybackTracker, voiceRecorderProvider: VoiceRecorderProvider ) { private var mediaPlayer: MediaPlayer? = null + private var currentPlayingId: String? = null private var voiceRecorder: VoiceRecorder = voiceRecorderProvider.provideVoiceRecorder() private val amplitudeList = mutableListOf<Int>() @@ -58,7 +59,7 @@ class VoiceMessageHelper @Inject constructor( amplitudeList.clear() attachmentData.waveform?.let { amplitudeList.addAll(it) - playbackTracker.updateCurrentRecording(VoiceMessagePlaybackTracker.RECORDING_ID, amplitudeList) + playbackTracker.updateCurrentRecording(AudioMessagePlaybackTracker.RECORDING_ID, amplitudeList) } } @@ -127,7 +128,7 @@ class VoiceMessageHelper @Inject constructor( fun startOrPauseRecordingPlayback() { voiceRecorder.getCurrentRecord()?.let { - startOrPausePlayback(VoiceMessagePlaybackTracker.RECORDING_ID, it) + startOrPausePlayback(AudioMessagePlaybackTracker.RECORDING_ID, it) } } @@ -136,7 +137,8 @@ class VoiceMessageHelper @Inject constructor( mediaPlayer?.stop() stopPlaybackTicker() stopRecordingAmplitudes() - if (playbackState is VoiceMessagePlaybackTracker.Listener.State.Playing) { + currentPlayingId = null + if (playbackState is AudioMessagePlaybackTracker.Listener.State.Playing) { playbackTracker.pausePlayback(id) } else { startPlayback(id, file) @@ -163,6 +165,7 @@ class VoiceMessageHelper @Inject constructor( seekTo(currentPlaybackTime) } } + currentPlayingId = id } catch (failure: Throwable) { Timber.e(failure, "Unable to start playback") throw VoiceFailure.UnableToPlay(failure) @@ -171,17 +174,24 @@ class VoiceMessageHelper @Inject constructor( } fun stopPlayback() { - playbackTracker.pausePlayback(VoiceMessagePlaybackTracker.RECORDING_ID) + playbackTracker.pausePlayback(AudioMessagePlaybackTracker.RECORDING_ID) mediaPlayer?.stop() stopPlaybackTicker() + currentPlayingId = null } fun movePlaybackTo(id: String, percentage: Float, totalDuration: Int) { val toMillisecond = (totalDuration * percentage).toInt() - playbackTracker.updateCurrentPlaybackTime(id, toMillisecond, percentage) + playbackTracker.pauseAllPlaybacks() - stopPlayback() - playbackTracker.pausePlayback(id) + if (currentPlayingId == id) { + mediaPlayer?.seekTo(toMillisecond) + playbackTracker.updatePlayingAtPlaybackTime(id, toMillisecond, percentage) + } else { + mediaPlayer?.pause() + playbackTracker.updatePausedAtPlaybackTime(id, toMillisecond, percentage) + stopPlaybackTicker() + } } private fun startRecordingAmplitudes() { @@ -200,7 +210,7 @@ class VoiceMessageHelper @Inject constructor( try { val maxAmplitude = voiceRecorder.getMaxAmplitude() amplitudeList.add(maxAmplitude) - playbackTracker.updateCurrentRecording(VoiceMessagePlaybackTracker.RECORDING_ID, amplitudeList) + playbackTracker.updateCurrentRecording(AudioMessagePlaybackTracker.RECORDING_ID, amplitudeList) } catch (e: IllegalStateException) { Timber.e(e, "Cannot get max amplitude. Amplitude recording timer will be stopped.") stopRecordingAmplitudes() @@ -233,7 +243,7 @@ class VoiceMessageHelper @Inject constructor( val currentPosition = mediaPlayer?.currentPosition ?: 0 val totalDuration = mediaPlayer?.duration ?: 0 val percentage = currentPosition.toFloat() / totalDuration - playbackTracker.updateCurrentPlaybackTime(id, currentPosition, percentage) + playbackTracker.updatePlayingAtPlaybackTime(id, currentPosition, percentage) } else { playbackTracker.stopPlayback(id) stopPlaybackTicker() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt index 091e9f7869..0da324ffc2 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerAction.kt @@ -17,6 +17,7 @@ package im.vector.app.features.home.room.detail.composer import im.vector.app.core.platform.VectorViewModelAction +import im.vector.app.features.command.ParsedCommand import im.vector.app.features.home.room.detail.composer.voice.VoiceMessageRecorderView import org.matrix.android.sdk.api.session.content.ContentAttachmentData import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent @@ -30,6 +31,7 @@ sealed class MessageComposerAction : VectorViewModelAction { data class UserIsTyping(val isTyping: Boolean) : MessageComposerAction() data class OnTextChanged(val text: CharSequence) : MessageComposerAction() data class OnEntersBackground(val composerText: String) : MessageComposerAction() + data class SlashCommandConfirmed(val parsedCommand: ParsedCommand) : MessageComposerAction() // Voice Message data class InitializeVoiceRecorder(val attachmentData: ContentAttachmentData) : MessageComposerAction() @@ -42,4 +44,5 @@ sealed class MessageComposerAction : VectorViewModelAction { data class EndAllVoiceActions(val deleteRecord: Boolean = true) : MessageComposerAction() data class VoiceWaveformTouchedUp(val eventId: String, val duration: Int, val percentage: Float) : MessageComposerAction() data class VoiceWaveformMovedTo(val eventId: String, val duration: Int, val percentage: Float) : MessageComposerAction() + data class AudioSeekBarMovedTo(val eventId: String, val duration: Int, val percentage: Float) : MessageComposerAction() } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt index fbc046b2d2..4c1f4d0c86 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewEvents.kt @@ -16,9 +16,9 @@ package im.vector.app.features.home.room.detail.composer -import androidx.annotation.StringRes import im.vector.app.core.platform.VectorViewEvents import im.vector.app.features.command.Command +import im.vector.app.features.command.ParsedCommand sealed class MessageComposerViewEvents : VectorViewEvents { @@ -30,13 +30,14 @@ sealed class MessageComposerViewEvents : VectorViewEvents { object MessageSent : SendMessageResult() data class JoinRoomCommandSuccess(val roomId: String) : SendMessageResult() - class SlashCommandError(val command: Command) : SendMessageResult() - class SlashCommandUnknown(val command: String) : SendMessageResult() - class SlashCommandNotSupportedInThreads(val command: Command) : SendMessageResult() - data class SlashCommandHandled(@StringRes val messageRes: Int? = null) : SendMessageResult() + data class SlashCommandError(val command: Command) : SendMessageResult() + data class SlashCommandUnknown(val command: String) : SendMessageResult() + data class SlashCommandNotSupportedInThreads(val command: Command) : SendMessageResult() object SlashCommandLoading : SendMessageResult() - data class SlashCommandResultOk(@StringRes val messageRes: Int? = null) : SendMessageResult() - class SlashCommandResultError(val throwable: Throwable) : SendMessageResult() + data class SlashCommandResultOk(val parsedCommand: ParsedCommand) : SendMessageResult() + data class SlashCommandResultError(val throwable: Throwable) : SendMessageResult() + + data class SlashCommandConfirmationRequest(val parsedCommand: ParsedCommand) : MessageComposerViewEvents() data class OpenRoomMemberProfile(val userId: String) : MessageComposerViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt index b06c42ffd3..236de240ee 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/MessageComposerViewModel.kt @@ -73,7 +73,7 @@ class MessageComposerViewModel @AssistedInject constructor( private val vectorPreferences: VectorPreferences, private val commandParser: CommandParser, private val rainbowGenerator: RainbowGenerator, - private val voiceMessageHelper: VoiceMessageHelper, + private val audioMessageHelper: AudioMessageHelper, private val analyticsTracker: AnalyticsTracker, private val voicePlayerHelper: VoicePlayerHelper ) : VectorViewModel<MessageComposerViewState, MessageComposerAction, MessageComposerViewEvents>(initialState) { @@ -90,7 +90,6 @@ class MessageComposerViewModel @AssistedInject constructor( } override fun handle(action: MessageComposerAction) { - Timber.v("Handle action: $action") when (action) { is MessageComposerAction.EnterEditMode -> handleEnterEditMode(action) is MessageComposerAction.EnterQuoteMode -> handleEnterQuoteMode(action) @@ -110,6 +109,8 @@ class MessageComposerViewModel @AssistedInject constructor( is MessageComposerAction.OnEntersBackground -> handleEntersBackground(action.composerText) is MessageComposerAction.VoiceWaveformTouchedUp -> handleVoiceWaveformTouchedUp(action) is MessageComposerAction.VoiceWaveformMovedTo -> handleVoiceWaveformMovedTo(action) + is MessageComposerAction.AudioSeekBarMovedTo -> handleAudioSeekBarMovedTo(action) + is MessageComposerAction.SlashCommandConfirmed -> handleSlashCommandConfirmed(action) } } @@ -197,7 +198,7 @@ class MessageComposerViewModel @AssistedInject constructor( } when (state.sendMode) { is SendMode.Regular -> { - when (val slashCommandResult = commandParser.parseSlashCommand( + when (val parsedCommand = commandParser.parseSlashCommand( textMessage = action.text, isInThreadTimeline = state.isInThreadTimeline())) { is ParsedCommand.ErrorNotACommand -> { @@ -215,118 +216,117 @@ class MessageComposerViewModel @AssistedInject constructor( popDraft() } is ParsedCommand.ErrorSyntax -> { - _viewEvents.post(MessageComposerViewEvents.SlashCommandError(slashCommandResult.command)) + _viewEvents.post(MessageComposerViewEvents.SlashCommandError(parsedCommand.command)) } is ParsedCommand.ErrorEmptySlashCommand -> { _viewEvents.post(MessageComposerViewEvents.SlashCommandUnknown("/")) } is ParsedCommand.ErrorUnknownSlashCommand -> { - _viewEvents.post(MessageComposerViewEvents.SlashCommandUnknown(slashCommandResult.slashCommand)) + _viewEvents.post(MessageComposerViewEvents.SlashCommandUnknown(parsedCommand.slashCommand)) } is ParsedCommand.ErrorCommandNotSupportedInThreads -> { - _viewEvents.post(MessageComposerViewEvents.SlashCommandNotSupportedInThreads(slashCommandResult.command)) + _viewEvents.post(MessageComposerViewEvents.SlashCommandNotSupportedInThreads(parsedCommand.command)) } is ParsedCommand.SendPlainText -> { // Send the text message to the room, without markdown if (state.rootThreadEventId != null) { room.replyInThread( rootThreadEventId = state.rootThreadEventId, - replyInThreadText = slashCommandResult.message, + replyInThreadText = parsedCommand.message, autoMarkdown = false) } else { - room.sendTextMessage(slashCommandResult.message, autoMarkdown = false) + room.sendTextMessage(parsedCommand.message, autoMarkdown = false) } _viewEvents.post(MessageComposerViewEvents.MessageSent) popDraft() } is ParsedCommand.ChangeRoomName -> { - handleChangeRoomNameSlashCommand(slashCommandResult) + handleChangeRoomNameSlashCommand(parsedCommand) } is ParsedCommand.Invite -> { - handleInviteSlashCommand(slashCommandResult) + handleInviteSlashCommand(parsedCommand) } is ParsedCommand.Invite3Pid -> { - handleInvite3pidSlashCommand(slashCommandResult) + handleInvite3pidSlashCommand(parsedCommand) } is ParsedCommand.SetUserPowerLevel -> { - handleSetUserPowerLevel(slashCommandResult) + handleSetUserPowerLevel(parsedCommand) } is ParsedCommand.ClearScalarToken -> { // TODO _viewEvents.post(MessageComposerViewEvents.SlashCommandNotImplemented) } is ParsedCommand.SetMarkdown -> { - vectorPreferences.setMarkdownEnabled(slashCommandResult.enable) - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk( - if (slashCommandResult.enable) R.string.markdown_has_been_enabled else R.string.markdown_has_been_disabled)) + vectorPreferences.setMarkdownEnabled(parsedCommand.enable) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.BanUser -> { - handleBanSlashCommand(slashCommandResult) + handleBanSlashCommand(parsedCommand) } is ParsedCommand.UnbanUser -> { - handleUnbanSlashCommand(slashCommandResult) + handleUnbanSlashCommand(parsedCommand) } is ParsedCommand.IgnoreUser -> { - handleIgnoreSlashCommand(slashCommandResult) + handleIgnoreSlashCommand(parsedCommand) } is ParsedCommand.UnignoreUser -> { - handleUnignoreSlashCommand(slashCommandResult) + handleUnignoreSlashCommand(parsedCommand) } is ParsedCommand.RemoveUser -> { - handleRemoveSlashCommand(slashCommandResult) + handleRemoveSlashCommand(parsedCommand) } is ParsedCommand.JoinRoom -> { - handleJoinToAnotherRoomSlashCommand(slashCommandResult) + handleJoinToAnotherRoomSlashCommand(parsedCommand) popDraft() } is ParsedCommand.PartRoom -> { - handlePartSlashCommand(slashCommandResult) + handlePartSlashCommand(parsedCommand) } is ParsedCommand.SendEmote -> { if (state.rootThreadEventId != null) { room.replyInThread( rootThreadEventId = state.rootThreadEventId, - replyInThreadText = slashCommandResult.message, + replyInThreadText = parsedCommand.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown) } else { - room.sendTextMessage(slashCommandResult.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown) + room.sendTextMessage(parsedCommand.message, msgType = MessageType.MSGTYPE_EMOTE, autoMarkdown = action.autoMarkdown) } - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.SendRainbow -> { - val message = slashCommandResult.message.toString() + val message = parsedCommand.message.toString() if (state.rootThreadEventId != null) { room.replyInThread( rootThreadEventId = state.rootThreadEventId, - replyInThreadText = slashCommandResult.message, + replyInThreadText = parsedCommand.message, formattedText = rainbowGenerator.generate(message)) } else { room.sendFormattedTextMessage(message, rainbowGenerator.generate(message)) } - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.SendRainbowEmote -> { - val message = slashCommandResult.message.toString() + val message = parsedCommand.message.toString() if (state.rootThreadEventId != null) { room.replyInThread( rootThreadEventId = state.rootThreadEventId, - replyInThreadText = slashCommandResult.message, + replyInThreadText = parsedCommand.message, msgType = MessageType.MSGTYPE_EMOTE, formattedText = rainbowGenerator.generate(message)) } else { room.sendFormattedTextMessage(message, rainbowGenerator.generate(message), MessageType.MSGTYPE_EMOTE) } - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.SendSpoiler -> { - val text = "[${stringProvider.getString(R.string.spoiler)}](${slashCommandResult.message})" - val formattedText = "<span data-mx-spoiler>${slashCommandResult.message}</span>" + val text = "[${stringProvider.getString(R.string.spoiler)}](${parsedCommand.message})" + val formattedText = "<span data-mx-spoiler>${parsedCommand.message}</span>" if (state.rootThreadEventId != null) { room.replyInThread( rootThreadEventId = state.rootThreadEventId, @@ -337,51 +337,51 @@ class MessageComposerViewModel @AssistedInject constructor( text, formattedText) } - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.SendShrug -> { - sendPrefixedMessage("¯\\_(ツ)_/¯", slashCommandResult.message, state.rootThreadEventId) - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + sendPrefixedMessage("¯\\_(ツ)_/¯", parsedCommand.message, state.rootThreadEventId) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.SendLenny -> { - sendPrefixedMessage("( ͡° ͜ʖ ͡°)", slashCommandResult.message, state.rootThreadEventId) - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + sendPrefixedMessage("( ͡° ͜ʖ ͡°)", parsedCommand.message, state.rootThreadEventId) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.SendChatEffect -> { - sendChatEffect(slashCommandResult) - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + sendChatEffect(parsedCommand) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } is ParsedCommand.ChangeTopic -> { - handleChangeTopicSlashCommand(slashCommandResult) + handleChangeTopicSlashCommand(parsedCommand) } is ParsedCommand.ChangeDisplayName -> { - handleChangeDisplayNameSlashCommand(slashCommandResult) + handleChangeDisplayNameSlashCommand(parsedCommand) } is ParsedCommand.ChangeDisplayNameForRoom -> { - handleChangeDisplayNameForRoomSlashCommand(slashCommandResult) + handleChangeDisplayNameForRoomSlashCommand(parsedCommand) } is ParsedCommand.ChangeRoomAvatar -> { - handleChangeRoomAvatarSlashCommand(slashCommandResult) + handleChangeRoomAvatarSlashCommand(parsedCommand) } is ParsedCommand.ChangeAvatarForRoom -> { - handleChangeAvatarForRoomSlashCommand(slashCommandResult) + handleChangeAvatarForRoomSlashCommand(parsedCommand) } is ParsedCommand.ShowUser -> { - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) - handleWhoisSlashCommand(slashCommandResult) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) + handleWhoisSlashCommand(parsedCommand) popDraft() } is ParsedCommand.DiscardSession -> { if (room.isEncrypted()) { session.cryptoService().discardOutboundSession(room.roomId) - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } else { - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) _viewEvents.post( MessageComposerViewEvents .ShowMessage(stringProvider.getString(R.string.command_description_discard_session_not_handled)) @@ -393,8 +393,8 @@ class MessageComposerViewModel @AssistedInject constructor( viewModelScope.launch(Dispatchers.IO) { try { val params = CreateSpaceParams().apply { - name = slashCommandResult.name - invitedUserIds.addAll(slashCommandResult.invitees) + name = parsedCommand.name + invitedUserIds.addAll(parsedCommand.invitees) } val spaceId = session.spaceService().createSpace(params) session.spaceService().getSpace(spaceId) @@ -405,7 +405,7 @@ class MessageComposerViewModel @AssistedInject constructor( true ) popDraft() - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) } catch (failure: Throwable) { _viewEvents.post(MessageComposerViewEvents.SlashCommandResultError(failure)) } @@ -416,7 +416,7 @@ class MessageComposerViewModel @AssistedInject constructor( _viewEvents.post(MessageComposerViewEvents.SlashCommandLoading) viewModelScope.launch(Dispatchers.IO) { try { - session.spaceService().getSpace(slashCommandResult.spaceId) + session.spaceService().getSpace(parsedCommand.spaceId) ?.addChildren( room.roomId, null, @@ -424,7 +424,7 @@ class MessageComposerViewModel @AssistedInject constructor( false ) popDraft() - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) } catch (failure: Throwable) { _viewEvents.post(MessageComposerViewEvents.SlashCommandResultError(failure)) } @@ -435,9 +435,9 @@ class MessageComposerViewModel @AssistedInject constructor( _viewEvents.post(MessageComposerViewEvents.SlashCommandLoading) viewModelScope.launch(Dispatchers.IO) { try { - session.spaceService().joinSpace(slashCommandResult.spaceIdOrAlias) + session.spaceService().joinSpace(parsedCommand.spaceIdOrAlias) popDraft() - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) } catch (failure: Throwable) { _viewEvents.post(MessageComposerViewEvents.SlashCommandResultError(failure)) } @@ -447,9 +447,9 @@ class MessageComposerViewModel @AssistedInject constructor( is ParsedCommand.LeaveRoom -> { viewModelScope.launch(Dispatchers.IO) { try { - session.leaveRoom(slashCommandResult.roomId) + session.leaveRoom(parsedCommand.roomId) popDraft() - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) } catch (failure: Throwable) { _viewEvents.post(MessageComposerViewEvents.SlashCommandResultError(failure)) } @@ -459,11 +459,11 @@ class MessageComposerViewModel @AssistedInject constructor( is ParsedCommand.UpgradeRoom -> { _viewEvents.post( MessageComposerViewEvents.ShowRoomUpgradeDialog( - slashCommandResult.newVersion, + parsedCommand.newVersion, room.roomSummary()?.isPublic ?: false ) ) - _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk()) + _viewEvents.post(MessageComposerViewEvents.SlashCommandResultOk(parsedCommand)) popDraft() } } @@ -646,19 +646,19 @@ class MessageComposerViewModel @AssistedInject constructor( } private fun handleChangeTopicSlashCommand(changeTopic: ParsedCommand.ChangeTopic) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(changeTopic) { room.updateTopic(changeTopic.topic) } } private fun handleInviteSlashCommand(invite: ParsedCommand.Invite) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(invite) { room.invite(invite.userId, invite.reason) } } private fun handleInvite3pidSlashCommand(invite: ParsedCommand.Invite3Pid) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(invite) { room.invite3pid(invite.threePid) } } @@ -671,19 +671,19 @@ class MessageComposerViewModel @AssistedInject constructor( ?.toContent() ?: return - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(setUserPowerLevel) { room.sendStateEvent(EventType.STATE_ROOM_POWER_LEVELS, stateKey = "", newPowerLevelsContent) } } private fun handleChangeDisplayNameSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayName) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(changeDisplayName) { session.setDisplayName(session.myUserId, changeDisplayName.displayName) } } private fun handlePartSlashCommand(command: ParsedCommand.PartRoom) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(command) { if (command.roomAlias == null) { // Leave the current room room @@ -699,25 +699,25 @@ class MessageComposerViewModel @AssistedInject constructor( } private fun handleRemoveSlashCommand(removeUser: ParsedCommand.RemoveUser) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(removeUser) { room.remove(removeUser.userId, removeUser.reason) } } private fun handleBanSlashCommand(ban: ParsedCommand.BanUser) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(ban) { room.ban(ban.userId, ban.reason) } } private fun handleUnbanSlashCommand(unban: ParsedCommand.UnbanUser) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(unban) { room.unban(unban.userId, unban.reason) } } private fun handleChangeRoomNameSlashCommand(changeRoomName: ParsedCommand.ChangeRoomName) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(changeRoomName) { room.updateName(changeRoomName.name) } } @@ -729,7 +729,7 @@ class MessageComposerViewModel @AssistedInject constructor( } private fun handleChangeDisplayNameForRoomSlashCommand(changeDisplayName: ParsedCommand.ChangeDisplayNameForRoom) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(changeDisplayName) { getMyRoomMemberContent() ?.copy(displayName = changeDisplayName.displayName) ?.toContent() @@ -740,13 +740,13 @@ class MessageComposerViewModel @AssistedInject constructor( } private fun handleChangeRoomAvatarSlashCommand(changeAvatar: ParsedCommand.ChangeRoomAvatar) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(changeAvatar) { room.sendStateEvent(EventType.STATE_ROOM_AVATAR, stateKey = "", RoomAvatarContent(changeAvatar.url).toContent()) } } private fun handleChangeAvatarForRoomSlashCommand(changeAvatar: ParsedCommand.ChangeAvatarForRoom) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(changeAvatar) { getMyRoomMemberContent() ?.copy(avatarUrl = changeAvatar.url) ?.toContent() @@ -757,13 +757,24 @@ class MessageComposerViewModel @AssistedInject constructor( } private fun handleIgnoreSlashCommand(ignore: ParsedCommand.IgnoreUser) { - launchSlashCommandFlowSuspendable { + launchSlashCommandFlowSuspendable(ignore) { session.ignoreUserIds(listOf(ignore.userId)) } } private fun handleUnignoreSlashCommand(unignore: ParsedCommand.UnignoreUser) { - launchSlashCommandFlowSuspendable { + _viewEvents.post(MessageComposerViewEvents.SlashCommandConfirmationRequest(unignore)) + } + + private fun handleSlashCommandConfirmed(action: MessageComposerAction.SlashCommandConfirmed) { + when (action.parsedCommand) { + is ParsedCommand.UnignoreUser -> handleUnignoreSlashCommandConfirmed(action.parsedCommand) + else -> TODO("Not handled yet") + } + } + + private fun handleUnignoreSlashCommandConfirmed(unignore: ParsedCommand.UnignoreUser) { + launchSlashCommandFlowSuspendable(unignore) { session.unIgnoreUserIds(listOf(unignore.userId)) } } @@ -813,18 +824,18 @@ class MessageComposerViewModel @AssistedInject constructor( private fun handleStartRecordingVoiceMessage() { try { - voiceMessageHelper.startRecording(room.roomId) + audioMessageHelper.startRecording(room.roomId) } catch (failure: Throwable) { _viewEvents.post(MessageComposerViewEvents.VoicePlaybackOrRecordingFailure(failure)) } } private fun handleEndRecordingVoiceMessage(isCancelled: Boolean, rootThreadEventId: String? = null) { - voiceMessageHelper.stopPlayback() + audioMessageHelper.stopPlayback() if (isCancelled) { - voiceMessageHelper.deleteRecording() + audioMessageHelper.deleteRecording() } else { - voiceMessageHelper.stopRecording(convertForSending = true)?.let { audioType -> + audioMessageHelper.stopRecording(convertForSending = true)?.let { audioType -> if (audioType.duration > 1000) { room.sendMedia( attachment = audioType.toContentAttachmentData(isVoiceMessage = true), @@ -832,7 +843,7 @@ class MessageComposerViewModel @AssistedInject constructor( roomIds = emptySet(), rootThreadEventId = rootThreadEventId) } else { - voiceMessageHelper.deleteRecording() + audioMessageHelper.deleteRecording() } } } @@ -847,7 +858,7 @@ class MessageComposerViewModel @AssistedInject constructor( // Conversion can fail, fallback to the original file in this case and let the player fail for us val convertedFile = voicePlayerHelper.convertFile(audioFile) ?: audioFile // Play can fail - voiceMessageHelper.startOrPausePlayback(action.eventId, convertedFile) + audioMessageHelper.startOrPausePlayback(action.eventId, convertedFile) } catch (failure: Throwable) { _viewEvents.post(MessageComposerViewEvents.VoicePlaybackOrRecordingFailure(failure)) } @@ -855,35 +866,38 @@ class MessageComposerViewModel @AssistedInject constructor( } private fun handlePlayOrPauseRecordingPlayback() { - voiceMessageHelper.startOrPauseRecordingPlayback() + audioMessageHelper.startOrPauseRecordingPlayback() } private fun handleEndAllVoiceActions(deleteRecord: Boolean) { - voiceMessageHelper.clearTracker() - voiceMessageHelper.stopAllVoiceActions(deleteRecord) + audioMessageHelper.clearTracker() + audioMessageHelper.stopAllVoiceActions(deleteRecord) } private fun handleInitializeVoiceRecorder(attachmentData: ContentAttachmentData) { - voiceMessageHelper.initializeRecorder(attachmentData) + audioMessageHelper.initializeRecorder(attachmentData) setState { copy(voiceRecordingUiState = VoiceMessageRecorderView.RecordingUiState.Draft) } } private fun handlePauseRecordingVoiceMessage() { - voiceMessageHelper.pauseRecording() + audioMessageHelper.pauseRecording() } private fun handleVoiceWaveformTouchedUp(action: MessageComposerAction.VoiceWaveformTouchedUp) { - voiceMessageHelper.movePlaybackTo(action.eventId, action.percentage, action.duration) + audioMessageHelper.movePlaybackTo(action.eventId, action.percentage, action.duration) } private fun handleVoiceWaveformMovedTo(action: MessageComposerAction.VoiceWaveformMovedTo) { - voiceMessageHelper.movePlaybackTo(action.eventId, action.percentage, action.duration) + audioMessageHelper.movePlaybackTo(action.eventId, action.percentage, action.duration) + } + + private fun handleAudioSeekBarMovedTo(action: MessageComposerAction.AudioSeekBarMovedTo) { + audioMessageHelper.movePlaybackTo(action.eventId, action.percentage, action.duration) } private fun handleEntersBackground(composerText: String) { // Always stop all voice actions. It may be playing in timeline or active recording - val playingAudioContent = voiceMessageHelper.stopAllVoiceActions(deleteRecord = false) - voiceMessageHelper.clearTracker() + val playingAudioContent = audioMessageHelper.stopAllVoiceActions(deleteRecord = false) val isVoiceRecording = com.airbnb.mvrx.withState(this) { it.isVoiceRecording } if (isVoiceRecording) { @@ -899,13 +913,13 @@ class MessageComposerViewModel @AssistedInject constructor( } } - private fun launchSlashCommandFlowSuspendable(block: suspend () -> Unit) { + private fun launchSlashCommandFlowSuspendable(parsedCommand: ParsedCommand, block: suspend () -> Unit) { _viewEvents.post(MessageComposerViewEvents.SlashCommandLoading) viewModelScope.launch { val event = try { block() popDraft() - MessageComposerViewEvents.SlashCommandResultOk() + MessageComposerViewEvents.SlashCommandResultOk(parsedCommand) } catch (failure: Throwable) { MessageComposerViewEvents.SlashCommandResultError(failure) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageRecorderView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageRecorderView.kt index ab37d1a48c..b898aaf114 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageRecorderView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageRecorderView.kt @@ -27,7 +27,7 @@ import im.vector.app.core.hardware.vibrate import im.vector.app.core.time.Clock import im.vector.app.core.utils.DimensionConverter import im.vector.app.databinding.ViewVoiceMessageRecorderBinding -import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlaybackTracker +import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker import im.vector.lib.core.utils.timer.CountUpTimer import javax.inject.Inject import kotlin.math.floor @@ -40,7 +40,7 @@ class VoiceMessageRecorderView @JvmOverloads constructor( context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0 -) : ConstraintLayout(context, attrs, defStyleAttr), VoiceMessagePlaybackTracker.Listener { +) : ConstraintLayout(context, attrs, defStyleAttr), AudioMessagePlaybackTracker.Listener { interface Callback { fun onVoiceRecordingStarted() @@ -222,16 +222,16 @@ class VoiceMessageRecorderView @JvmOverloads constructor( recordingTicker = null } - override fun onUpdate(state: VoiceMessagePlaybackTracker.Listener.State) { + override fun onUpdate(state: AudioMessagePlaybackTracker.Listener.State) { when (state) { - is VoiceMessagePlaybackTracker.Listener.State.Recording -> { + is AudioMessagePlaybackTracker.Listener.State.Recording -> { voiceMessageViews.renderRecordingWaveform(state.amplitudeList.toTypedArray()) } - is VoiceMessagePlaybackTracker.Listener.State.Playing -> { + is AudioMessagePlaybackTracker.Listener.State.Playing -> { voiceMessageViews.renderPlaying(state) } - is VoiceMessagePlaybackTracker.Listener.State.Paused, - is VoiceMessagePlaybackTracker.Listener.State.Idle -> { + is AudioMessagePlaybackTracker.Listener.State.Paused, + is AudioMessagePlaybackTracker.Listener.State.Idle -> { voiceMessageViews.renderIdle() } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageViews.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageViews.kt index 752d40fe61..9f9c6bdbba 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageViews.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/composer/voice/VoiceMessageViews.kt @@ -35,7 +35,7 @@ import im.vector.app.core.utils.DimensionConverter import im.vector.app.databinding.ViewVoiceMessageRecorderBinding import im.vector.app.features.home.room.detail.composer.voice.VoiceMessageRecorderView.DraggingState import im.vector.app.features.home.room.detail.composer.voice.VoiceMessageRecorderView.RecordingUiState -import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlaybackTracker +import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.voice.AudioWaveformView @@ -314,7 +314,7 @@ class VoiceMessageViews( views.voicePlaybackWaveform.post { views.voicePlaybackWaveform.clear() } } - fun renderPlaying(state: VoiceMessagePlaybackTracker.Listener.State.Playing) { + fun renderPlaying(state: AudioMessagePlaybackTracker.Listener.State.Playing) { views.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_pause) views.voicePlaybackControlButton.contentDescription = resources.getString(R.string.a11y_pause_voice_message) val formattedTimerText = DateUtils.formatElapsedTime((state.playbackTime / 1000).toLong()) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt index 54cd70ccae..bd1f554eaa 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/TimelineEventController.kt @@ -153,6 +153,8 @@ class TimelineEventController @Inject constructor(private val dateFormatter: Vec fun onVoiceWaveformTouchedUp(eventId: String, duration: Int, percentage: Float) fun onVoiceWaveformMovedTo(eventId: String, duration: Int, percentage: Float) + fun onAudioSeekBarMovedTo(eventId: String, duration: Int, percentage: Float) + fun onAddMoreReaction(event: TimelineEvent) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/LocationUiData.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/LocationUiData.kt new file mode 100644 index 0000000000..c50c649221 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/LocationUiData.kt @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.detail.timeline.action + +import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvider + +/** + * Data used to display Location data in the message bottom sheet + */ +data class LocationUiData( + val locationUrl: String, + val locationOwnerId: String?, + val locationPinProvider: LocationPinProvider, +) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt index 307be220d3..41916c609d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsEpoxyController.kt @@ -46,8 +46,8 @@ import im.vector.app.features.media.ImageContentRenderer import im.vector.app.features.settings.VectorPreferences import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import org.matrix.android.sdk.api.extensions.orFalse -import org.matrix.android.sdk.api.extensions.orTrue import org.matrix.android.sdk.api.failure.Failure +import org.matrix.android.sdk.api.session.events.model.isLocationMessage import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageLocationContent import org.matrix.android.sdk.api.session.room.send.SendState @@ -80,12 +80,7 @@ class MessageActionsEpoxyController @Inject constructor( val formattedDate = dateFormatter.format(date, DateFormatKind.MESSAGE_DETAIL) val body = state.messageBody.linkify(host.listener) val bindingOptions = spanUtils.getBindingOptions(body) - - val locationContent = state.timelineEvent()?.root?.getClearContent() - ?.toModel<MessageLocationContent>(catchError = true) - val locationUrl = locationContent?.toLocationData() - ?.let { urlMapProvider.buildStaticMapUrl(it, INITIAL_MAP_ZOOM_IN_TIMELINE, 1200, 800) } - val locationOwnerId = if (locationContent?.isSelfLocation().orTrue()) state.informationData.matrixItem.id else null + val locationUiData = buildLocationUiData(state) bottomSheetMessagePreviewItem { id("preview") @@ -99,9 +94,7 @@ class MessageActionsEpoxyController @Inject constructor( body(body.toEpoxyCharSequence()) bodyDetails(host.eventDetailsFormatter.format(state.timelineEvent()?.root)?.toEpoxyCharSequence()) time(formattedDate) - locationUrl(locationUrl) - locationPinProvider(host.locationPinProvider) - locationOwnerId(locationOwnerId) + locationUiData(locationUiData) } // Send state @@ -222,6 +215,23 @@ class MessageActionsEpoxyController @Inject constructor( } } + private fun buildLocationUiData(state: MessageActionState): LocationUiData? { + if (state.timelineEvent()?.root?.isLocationMessage() != true) return null + + val locationContent = state.timelineEvent()?.root?.getClearContent().toModel<MessageLocationContent>(catchError = true) + ?: return null + val locationUrl = locationContent.toLocationData() + ?.let { urlMapProvider.buildStaticMapUrl(it, INITIAL_MAP_ZOOM_IN_TIMELINE, 1200, 800) } + ?: return null + val locationOwnerId = if (locationContent.isSelfLocation()) state.informationData.matrixItem.id else null + + return LocationUiData( + locationUrl = locationUrl, + locationOwnerId = locationOwnerId, + locationPinProvider = locationPinProvider, + ) + } + private fun EventSharedAction.shouldShowBetaLabel(): Boolean = this is EventSharedAction.ReplyInThread && !vectorPreferences.areThreadMessagesEnabled() diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt index 126a7273b8..15bf0e2e0d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/action/MessageActionsViewModel.kt @@ -454,6 +454,10 @@ class MessageActionsViewModel @AssistedInject constructor( actionPermissions: ActionPermissions): Boolean { // We let reply in thread visible even if threads are not enabled, with an enhanced flow to attract users // if (!vectorPreferences.areThreadMessagesEnabled()) return false + // Disable beta prompt if the homeserver do not support threads + if (!vectorPreferences.areThreadMessagesEnabled() && + !session.getHomeServerCapabilities().canUseThreading) return false + if (initialState.isFromThreadTimeline) return false if (event.root.isThread()) return false if (event.root.getClearType() != EventType.MESSAGE && diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt index 0e9342fa05..cba00957fa 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryEpoxyController.kt @@ -38,7 +38,7 @@ import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.message.MessageTextContent import org.matrix.android.sdk.api.util.ContentUtils.extractUsefulTextFromReply -import org.matrix.android.sdk.internal.session.room.send.TextContent +import org.matrix.android.sdk.api.util.TextContent import java.util.Calendar import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt index 9abc67e41f..e1d4d71c6a 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/edithistory/ViewEditHistoryViewModel.kt @@ -30,8 +30,8 @@ import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.isReply -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import timber.log.Timber import java.util.UUID diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt index 2005f66bf3..cd8ca8966b 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptedItemFactory.kt @@ -33,8 +33,8 @@ import me.gujun.android.span.image import me.gujun.android.span.span import org.matrix.android.sdk.api.session.crypto.MXCryptoError import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent import javax.inject.Inject // This class handles timeline events who haven't been successfully decrypted diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt index 0cb86a5c1c..89899a52e0 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/EncryptionItemFactory.kt @@ -24,11 +24,11 @@ import im.vector.app.features.home.room.detail.timeline.helper.MessageInformatio import im.vector.app.features.home.room.detail.timeline.helper.MessageItemAttributesFactory import im.vector.app.features.home.room.detail.timeline.item.StatusTileTimelineItem import im.vector.app.features.home.room.detail.timeline.item.StatusTileTimelineItem_ +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.model.event.EncryptionEventContent import javax.inject.Inject class EncryptionItemFactory @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationMessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationMessageItemFactory.kt new file mode 100644 index 0000000000..9bc148a562 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/LiveLocationMessageItemFactory.kt @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.detail.timeline.factory + +import im.vector.app.core.epoxy.VectorEpoxyModel +import im.vector.app.core.utils.DimensionConverter +import im.vector.app.features.home.room.detail.timeline.helper.AvatarSizeProvider +import im.vector.app.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider +import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem +import im.vector.app.features.home.room.detail.timeline.item.MessageLiveLocationStartItem +import im.vector.app.features.home.room.detail.timeline.item.MessageLiveLocationStartItem_ +import org.matrix.android.sdk.api.extensions.orFalse +import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationBeaconContent +import javax.inject.Inject + +class LiveLocationMessageItemFactory @Inject constructor( + private val dimensionConverter: DimensionConverter, + private val timelineMediaSizeProvider: TimelineMediaSizeProvider, + private val avatarSizeProvider: AvatarSizeProvider, +) { + + fun create( + liveLocationContent: LiveLocationBeaconContent, + highlight: Boolean, + attributes: AbsMessageItem.Attributes, + ): VectorEpoxyModel<*>? { + // TODO handle location received and stopped states + return when { + isLiveRunning(liveLocationContent) -> buildStartLiveItem(highlight, attributes) + else -> null + } + } + + private fun isLiveRunning(liveLocationContent: LiveLocationBeaconContent): Boolean { + return liveLocationContent.getBestBeaconInfo()?.isLive.orFalse() && liveLocationContent.hasTimedOut.not() + } + + private fun buildStartLiveItem( + highlight: Boolean, + attributes: AbsMessageItem.Attributes, + ): MessageLiveLocationStartItem { + val width = timelineMediaSizeProvider.getMaxSize().first + val height = dimensionConverter.dpToPx(MessageItemFactory.MESSAGE_LOCATION_ITEM_HEIGHT_IN_DP) + + return MessageLiveLocationStartItem_() + .attributes(attributes) + .mapWidth(width) + .mapHeight(height) + .highlighted(highlight) + .leftGuideline(avatarSizeProvider.leftGuideline) + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt index a50224c5e5..46029a9d6e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MergedHeaderItemFactory.kt @@ -33,16 +33,16 @@ import im.vector.app.features.home.room.detail.timeline.item.MergedSimilarEvents import im.vector.app.features.home.room.detail.timeline.item.MergedSimilarEventsItem_ import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayoutFactory import im.vector.app.features.home.room.detail.timeline.tools.createLinkMovementMethod +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.PowerLevelsContent import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.model.event.EncryptionEventContent import javax.inject.Inject class MergedHeaderItemFactory @Inject constructor(private val activeSessionHolder: ActiveSessionHolder, diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt index 2ade85e33c..74f2573850 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/MessageItemFactory.kt @@ -34,6 +34,7 @@ import im.vector.app.core.resources.StringProvider import im.vector.app.core.utils.DimensionConverter import im.vector.app.core.utils.containsOnlyEmojis import im.vector.app.features.home.room.detail.timeline.TimelineEventController +import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker import im.vector.app.features.home.room.detail.timeline.helper.AvatarSizeProvider import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadStateTrackerBinder import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder @@ -41,8 +42,9 @@ import im.vector.app.features.home.room.detail.timeline.helper.LocationPinProvid import im.vector.app.features.home.room.detail.timeline.helper.MessageInformationDataFactory import im.vector.app.features.home.room.detail.timeline.helper.MessageItemAttributesFactory import im.vector.app.features.home.room.detail.timeline.helper.TimelineMediaSizeProvider -import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlaybackTracker import im.vector.app.features.home.room.detail.timeline.item.AbsMessageItem +import im.vector.app.features.home.room.detail.timeline.item.MessageAudioItem +import im.vector.app.features.home.room.detail.timeline.item.MessageAudioItem_ import im.vector.app.features.home.room.detail.timeline.item.MessageFileItem import im.vector.app.features.home.room.detail.timeline.item.MessageFileItem_ import im.vector.app.features.home.room.detail.timeline.item.MessageImageVideoItem @@ -92,9 +94,12 @@ import me.gujun.android.span.span import org.matrix.android.sdk.api.MatrixUrls.isMxcUrl import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.attachments.toElementToDecrypt import org.matrix.android.sdk.api.session.events.model.RelationType +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent import org.matrix.android.sdk.api.session.events.model.isThread import org.matrix.android.sdk.api.session.events.model.toModel +import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationBeaconContent import org.matrix.android.sdk.api.session.room.model.message.MessageAudioContent import org.matrix.android.sdk.api.session.room.model.message.MessageContent import org.matrix.android.sdk.api.session.room.model.message.MessageContentWithFormattedBody @@ -110,14 +115,11 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageVerification import org.matrix.android.sdk.api.session.room.model.message.MessageVideoContent import org.matrix.android.sdk.api.session.room.model.message.PollAnswer import org.matrix.android.sdk.api.session.room.model.message.PollType -import org.matrix.android.sdk.api.session.room.model.message.getFileName import org.matrix.android.sdk.api.session.room.model.message.getFileUrl import org.matrix.android.sdk.api.session.room.model.message.getThumbnailUrl import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import org.matrix.android.sdk.api.util.MimeTypes -import org.matrix.android.sdk.internal.crypto.attachments.toElementToDecrypt -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent -import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage import javax.inject.Inject class MessageItemFactory @Inject constructor( @@ -141,10 +143,11 @@ class MessageItemFactory @Inject constructor( private val lightweightSettingsStorage: LightweightSettingsStorage, private val spanUtils: SpanUtils, private val session: Session, - private val voiceMessagePlaybackTracker: VoiceMessagePlaybackTracker, + private val audioMessagePlaybackTracker: AudioMessagePlaybackTracker, private val locationPinProvider: LocationPinProvider, private val vectorPreferences: VectorPreferences, private val urlMapProvider: UrlMapProvider, + private val liveLocationMessageItemFactory: LiveLocationMessageItemFactory, ) { // TODO inject this properly? @@ -202,13 +205,7 @@ class MessageItemFactory @Inject constructor( is MessageNoticeContent -> buildNoticeMessageItem(messageContent, informationData, highlight, callback, attributes) is MessageVideoContent -> buildVideoMessageItem(messageContent, informationData, highlight, callback, attributes) is MessageFileContent -> buildFileMessageItem(messageContent, highlight, attributes) - is MessageAudioContent -> { - if (true || messageContent.voiceMessageIndicator != null) { - buildVoiceMessageItem(params, messageContent, informationData, highlight, attributes) - } else { - buildAudioMessageItem(messageContent, informationData, highlight, attributes) - } - } + is MessageAudioContent -> buildAudioContent(params, messageContent, informationData, highlight, attributes) is MessageVerificationRequestContent -> buildVerificationRequestMessageItem(messageContent, informationData, highlight, callback, attributes) is MessagePollContent -> buildPollItem(messageContent, informationData, highlight, callback, attributes) is MessageLocationContent -> { @@ -218,6 +215,7 @@ class MessageItemFactory @Inject constructor( buildMessageTextItem(messageContent.body, false, informationData, highlight, callback, attributes) } } + is LiveLocationBeaconContent -> liveLocationMessageItemFactory.create(messageContent, highlight, attributes) else -> buildNotHandledMessageItem(messageContent, informationData, highlight, callback, attributes) } return messageItem?.apply { @@ -232,7 +230,7 @@ class MessageItemFactory @Inject constructor( attributes: AbsMessageItem.Attributes, ): MessageLocationItem? { val width = timelineMediaSizeProvider.getMaxSize().first - val height = dimensionConverter.dpToPx(200) + val height = dimensionConverter.dpToPx(MESSAGE_LOCATION_ITEM_HEIGHT_IN_DP) val locationUrl = locationContent.toLocationData()?.let { urlMapProvider.buildStaticMapUrl(it, INITIAL_MAP_ZOOM_IN_TIMELINE, width, height) @@ -280,9 +278,9 @@ class MessageItemFactory @Inject constructor( } private fun createPollState( - informationData: MessageInformationData, - pollResponseSummary: PollResponseData?, - pollContent: MessagePollContent, + informationData: MessageInformationData, + pollResponseSummary: PollResponseData?, + pollContent: MessagePollContent, ): PollState = when { !informationData.sendState.isSent() -> Sending pollResponseSummary?.isClosed.orFalse() -> Ended @@ -292,8 +290,8 @@ class MessageItemFactory @Inject constructor( } private fun List<PollAnswer>.mapToOptions( - pollState: PollState, - informationData: MessageInformationData, + pollState: PollState, + informationData: MessageInformationData, ) = map { answer -> val pollResponseSummary = informationData.pollResponseAggregatedSummary val winnerVoteCount = pollResponseSummary?.winnerVoteCount @@ -315,9 +313,9 @@ class MessageItemFactory @Inject constructor( } private fun createPollQuestion( - informationData: MessageInformationData, - question: String, - callback: TimelineEventController.Callback?, + informationData: MessageInformationData, + question: String, + callback: TimelineEventController.Callback?, ) = if (informationData.hasBeenEdited) { annotateWithEdited(question, callback, informationData) } else { @@ -325,8 +323,8 @@ class MessageItemFactory @Inject constructor( }.toEpoxyCharSequence() private fun createTotalVotesText( - pollState: PollState, - pollResponseSummary: PollResponseData?, + pollState: PollState, + pollResponseSummary: PollResponseData?, ): String { val votes = pollResponseSummary?.totalVotes ?: 0 return when { @@ -339,58 +337,62 @@ class MessageItemFactory @Inject constructor( } private fun buildAudioMessageItem( - messageContent: MessageAudioContent, - @Suppress("UNUSED_PARAMETER") - informationData: MessageInformationData, - highlight: Boolean, - attributes: AbsMessageItem.Attributes, - ): MessageFileItem? { - val fileUrl = messageContent.getFileUrl()?.let { - if (informationData.sentByMe && !informationData.sendState.isSent()) { - it - } else { - it.takeIf { it.isMxcUrl() } - } - } ?: "" - return MessageFileItem_() - .attributes(attributes) - .izLocalFile(localFilesHelper.isLocalFile(fileUrl)) - .izDownloaded(session.fileService().isFileInCache( - fileUrl, - messageContent.getFileName(), - messageContent.mimeType, - messageContent.encryptedFileInfo?.toElementToDecrypt()) - ) - .mxcUrl(fileUrl) - .contentUploadStateTrackerBinder(contentUploadStateTrackerBinder) - .contentDownloadStateTrackerBinder(contentDownloadStateTrackerBinder) - .highlighted(highlight) - .leftGuideline(avatarSizeProvider.leftGuideline) - .filename(messageContent.body) - .iconRes(R.drawable.ic_headphones) + params: TimelineItemFactoryParams, + messageContent: MessageAudioContent, + informationData: MessageInformationData, + highlight: Boolean, + attributes: AbsMessageItem.Attributes + ): MessageAudioItem { + val fileUrl = getAudioFileUrl(messageContent, informationData) + val playbackControlButtonClickListener = createOnPlaybackButtonClickListener(messageContent, informationData, params) + val duration = messageContent.audioInfo?.duration ?: 0 + + return MessageAudioItem_() + .attributes(attributes) + .filename(messageContent.body) + .duration(messageContent.audioInfo?.duration ?: 0) + .playbackControlButtonClickListener(playbackControlButtonClickListener) + .audioMessagePlaybackTracker(audioMessagePlaybackTracker) + .isLocalFile(localFilesHelper.isLocalFile(fileUrl)) + .fileSize(messageContent.audioInfo?.size ?: 0L) + .onSeek { params.callback?.onAudioSeekBarMovedTo(informationData.eventId, duration, it) } + .mxcUrl(fileUrl) + .contentUploadStateTrackerBinder(contentUploadStateTrackerBinder) + .contentDownloadStateTrackerBinder(contentDownloadStateTrackerBinder) + .highlighted(highlight) + .leftGuideline(avatarSizeProvider.leftGuideline) + } + + private fun getAudioFileUrl( + messageContent: MessageAudioContent, + informationData: MessageInformationData, + ) = messageContent.getFileUrl()?.let { + if (informationData.sentByMe && !informationData.sendState.isSent()) { + it + } else { + it.takeIf { it.isMxcUrl() } + } + } ?: "" + + private fun createOnPlaybackButtonClickListener( + messageContent: MessageAudioContent, + informationData: MessageInformationData, + params: TimelineItemFactoryParams, + ) = object : ClickListener { + override fun invoke(view: View) { + params.callback?.onVoiceControlButtonClicked(informationData.eventId, messageContent) + } } private fun buildVoiceMessageItem( - params: TimelineItemFactoryParams, - messageContent: MessageAudioContent, - @Suppress("UNUSED_PARAMETER") - informationData: MessageInformationData, - highlight: Boolean, - attributes: AbsMessageItem.Attributes, - ): MessageVoiceItem? { - val fileUrl = messageContent.getFileUrl()?.let { - if (informationData.sentByMe && !informationData.sendState.isSent()) { - it - } else { - it.takeIf { it.isMxcUrl() } - } - } ?: "" - - val playbackControlButtonClickListener: ClickListener = object : ClickListener { - override fun invoke(view: View) { - params.callback?.onVoiceControlButtonClicked(informationData.eventId, messageContent) - } - } + params: TimelineItemFactoryParams, + messageContent: MessageAudioContent, + informationData: MessageInformationData, + highlight: Boolean, + attributes: AbsMessageItem.Attributes + ): MessageVoiceItem { + val fileUrl = getAudioFileUrl(messageContent, informationData) + val playbackControlButtonClickListener = createOnPlaybackButtonClickListener(messageContent, informationData, params) val waveformTouchListener: MessageVoiceItem.WaveformTouchListener = object : MessageVoiceItem.WaveformTouchListener { override fun onWaveformTouchedUp(percentage: Float) { @@ -410,14 +412,8 @@ class MessageItemFactory @Inject constructor( .waveform(messageContent.audioWaveformInfo?.waveform?.toFft().orEmpty()) .playbackControlButtonClickListener(playbackControlButtonClickListener) .waveformTouchListener(waveformTouchListener) - .voiceMessagePlaybackTracker(voiceMessagePlaybackTracker) - .izLocalFile(localFilesHelper.isLocalFile(fileUrl)) - .izDownloaded(session.fileService().isFileInCache( - fileUrl, - messageContent.getFileName(), - messageContent.mimeType, - messageContent.encryptedFileInfo?.toElementToDecrypt()) - ) + .audioMessagePlaybackTracker(audioMessagePlaybackTracker) + .isLocalFile(localFilesHelper.isLocalFile(fileUrl)) .mxcUrl(fileUrl) .contentUploadStateTrackerBinder(contentUploadStateTrackerBinder) .contentDownloadStateTrackerBinder(contentDownloadStateTrackerBinder) @@ -472,13 +468,13 @@ class MessageItemFactory @Inject constructor( messageContent: MessageFileContent, highlight: Boolean, attributes: AbsMessageItem.Attributes, - ): MessageFileItem? { + ): MessageFileItem { val mxcUrl = messageContent.getFileUrl() ?: "" return MessageFileItem_() .attributes(attributes) .leftGuideline(avatarSizeProvider.leftGuideline) - .izLocalFile(localFilesHelper.isLocalFile(messageContent.getFileUrl())) - .izDownloaded(session.fileService().isFileInCache(messageContent)) + .isLocalFile(localFilesHelper.isLocalFile(messageContent.getFileUrl())) + .isDownloaded(session.fileService().isFileInCache(messageContent)) .mxcUrl(mxcUrl) .contentUploadStateTrackerBinder(contentUploadStateTrackerBinder) .contentDownloadStateTrackerBinder(contentDownloadStateTrackerBinder) @@ -487,13 +483,24 @@ class MessageItemFactory @Inject constructor( .iconRes(R.drawable.ic_paperclip) } + private fun buildAudioContent( + params: TimelineItemFactoryParams, + messageContent: MessageAudioContent, + informationData: MessageInformationData, + highlight: Boolean, + attributes: AbsMessageItem.Attributes, + ) = if (true || messageContent.voiceMessageIndicator != null) { + buildVoiceMessageItem(params, messageContent, informationData, highlight, attributes) + } else { + buildAudioMessageItem(params, messageContent, informationData, highlight, attributes) + } + private fun buildNotHandledMessageItem( - messageContent: MessageContent, - informationData: MessageInformationData, - highlight: Boolean, - callback: TimelineEventController.Callback?, - attributes: AbsMessageItem.Attributes, - ): MessageTextItem? { + messageContent: MessageContent, + informationData: MessageInformationData, + highlight: Boolean, + callback: TimelineEventController.Callback?, + attributes: AbsMessageItem.Attributes): MessageTextItem? { // For compatibility reason we should display the body return buildMessageTextItem(messageContent.body, false, informationData, highlight, callback, attributes) } @@ -795,5 +802,6 @@ class MessageItemFactory @Inject constructor( companion object { private const val MAX_NUMBER_OF_EMOJI_FOR_BIG_FONT = 5 + const val MESSAGE_LOCATION_ITEM_HEIGHT_IN_DP = 200 } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactory.kt index f9d2613e27..b5d620658e 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/TimelineItemFactory.kt @@ -26,17 +26,19 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import timber.log.Timber import javax.inject.Inject -class TimelineItemFactory @Inject constructor(private val messageItemFactory: MessageItemFactory, - private val encryptedItemFactory: EncryptedItemFactory, - private val noticeItemFactory: NoticeItemFactory, - private val defaultItemFactory: DefaultItemFactory, - private val encryptionItemFactory: EncryptionItemFactory, - private val roomCreateItemFactory: RoomCreateItemFactory, - private val widgetItemFactory: WidgetItemFactory, - private val verificationConclusionItemFactory: VerificationItemFactory, - private val callItemFactory: CallItemFactory, - private val decryptionFailureTracker: DecryptionFailureTracker, - private val timelineEventVisibilityHelper: TimelineEventVisibilityHelper) { +class TimelineItemFactory @Inject constructor( + private val messageItemFactory: MessageItemFactory, + private val encryptedItemFactory: EncryptedItemFactory, + private val noticeItemFactory: NoticeItemFactory, + private val defaultItemFactory: DefaultItemFactory, + private val encryptionItemFactory: EncryptionItemFactory, + private val roomCreateItemFactory: RoomCreateItemFactory, + private val widgetItemFactory: WidgetItemFactory, + private val verificationConclusionItemFactory: VerificationItemFactory, + private val callItemFactory: CallItemFactory, + private val decryptionFailureTracker: DecryptionFailureTracker, + private val timelineEventVisibilityHelper: TimelineEventVisibilityHelper, +) { /** * Reminder: nextEvent is older and prevEvent is newer. @@ -75,16 +77,17 @@ class TimelineItemFactory @Inject constructor(private val messageItemFactory: Me EventType.STATE_ROOM_ALIASES, EventType.STATE_SPACE_CHILD, EventType.STATE_SPACE_PARENT, - EventType.STATE_ROOM_POWER_LEVELS -> { + EventType.STATE_ROOM_POWER_LEVELS -> { noticeItemFactory.create(params) } EventType.STATE_ROOM_WIDGET_LEGACY, - EventType.STATE_ROOM_WIDGET -> widgetItemFactory.create(params) - EventType.STATE_ROOM_ENCRYPTION -> encryptionItemFactory.create(params) + EventType.STATE_ROOM_WIDGET -> widgetItemFactory.create(params) + EventType.STATE_ROOM_ENCRYPTION -> encryptionItemFactory.create(params) // State room create - EventType.STATE_ROOM_CREATE -> roomCreateItemFactory.create(params) + EventType.STATE_ROOM_CREATE -> roomCreateItemFactory.create(params) + in EventType.STATE_ROOM_BEACON_INFO -> messageItemFactory.create(params) // Unhandled state event types - else -> { + else -> { // Should only happen when shouldShowHiddenEvents() settings is ON Timber.v("State event type ${event.root.type} not handled") defaultItemFactory.create(params) diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/VerificationItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/VerificationItemFactory.kt index 16cf73cbb0..fb8f8fce9d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/VerificationItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/factory/VerificationItemFactory.kt @@ -25,9 +25,9 @@ import im.vector.app.features.home.room.detail.timeline.helper.MessageInformatio import im.vector.app.features.home.room.detail.timeline.helper.MessageItemAttributesFactory import im.vector.app.features.home.room.detail.timeline.item.StatusTileTimelineItem import im.vector.app.features.home.room.detail.timeline.item.StatusTileTimelineItem_ -import org.matrix.android.sdk.api.crypto.VerificationState import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.verification.CancelCode +import org.matrix.android.sdk.api.session.crypto.verification.VerificationState import org.matrix.android.sdk.api.session.crypto.verification.safeValueOf import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.RelationType diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt index 8b44bf4c97..302d8c84fa 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/DisplayableEventFormatter.kt @@ -59,7 +59,7 @@ class DisplayableEventFormatter @Inject constructor( val senderName = timelineEvent.senderInfo.disambiguatedDisplayName return when (timelineEvent.root.getClearType()) { - EventType.MESSAGE -> { + EventType.MESSAGE -> { timelineEvent.getLastMessageContent()?.let { messageContent -> when (messageContent.msgType) { MessageType.MSGTYPE_TEXT -> { @@ -100,17 +100,17 @@ class DisplayableEventFormatter @Inject constructor( } } ?: span { } } - EventType.STICKER -> { + EventType.STICKER -> { simpleFormat(senderName, stringProvider.getString(R.string.send_a_sticker), appendAuthor) } - EventType.REACTION -> { + EventType.REACTION -> { timelineEvent.root.getClearContent().toModel<ReactionContent>()?.relatesTo?.let { val emojiSpanned = emojiSpanify.spanify(stringProvider.getString(R.string.sent_a_reaction, it.key)) simpleFormat(senderName, emojiSpanned, appendAuthor) } ?: span { } } EventType.KEY_VERIFICATION_CANCEL, - EventType.KEY_VERIFICATION_DONE -> { + EventType.KEY_VERIFICATION_DONE -> { // cancel and done can appear in timeline, so should have representation simpleFormat(senderName, stringProvider.getString(R.string.sent_verification_conclusion), appendAuthor) } @@ -119,20 +119,23 @@ class DisplayableEventFormatter @Inject constructor( EventType.KEY_VERIFICATION_MAC, EventType.KEY_VERIFICATION_KEY, EventType.KEY_VERIFICATION_READY, - EventType.CALL_CANDIDATES -> { + EventType.CALL_CANDIDATES -> { span { } } - in EventType.POLL_START -> { + in EventType.POLL_START -> { timelineEvent.root.getClearContent().toModel<MessagePollContent>(catchError = true)?.getBestPollCreationInfo()?.question?.getBestQuestion() ?: stringProvider.getString(R.string.sent_a_poll) } - in EventType.POLL_RESPONSE -> { + in EventType.POLL_RESPONSE -> { stringProvider.getString(R.string.poll_response_room_list_preview) } - in EventType.POLL_END -> { + in EventType.POLL_END -> { stringProvider.getString(R.string.poll_end_room_list_preview) } - else -> { + in EventType.STATE_ROOM_BEACON_INFO -> { + simpleFormat(senderName, stringProvider.getString(R.string.sent_live_location), appendAuthor) + } + else -> { span { text = noticeEventFormatter.format(timelineEvent, isDm) ?: "" textStyle = "italic" @@ -167,7 +170,7 @@ class DisplayableEventFormatter @Inject constructor( } return when (event.getClearType()) { - EventType.MESSAGE -> { + EventType.MESSAGE -> { (event.getClearContent().toModel() as? MessageContent)?.let { messageContent -> when (messageContent.msgType) { MessageType.MSGTYPE_TEXT -> { @@ -208,25 +211,28 @@ class DisplayableEventFormatter @Inject constructor( } } ?: span { } } - EventType.STICKER -> { + EventType.STICKER -> { stringProvider.getString(R.string.send_a_sticker) } - EventType.REACTION -> { + EventType.REACTION -> { event.getClearContent().toModel<ReactionContent>()?.relatesTo?.let { emojiSpanify.spanify(stringProvider.getString(R.string.sent_a_reaction, it.key)) } ?: span { } } - in EventType.POLL_START -> { + in EventType.POLL_START -> { event.getClearContent().toModel<MessagePollContent>(catchError = true)?.pollCreationInfo?.question?.question ?: stringProvider.getString(R.string.sent_a_poll) } - in EventType.POLL_RESPONSE -> { + in EventType.POLL_RESPONSE -> { stringProvider.getString(R.string.poll_response_room_list_preview) } - in EventType.POLL_END -> { + in EventType.POLL_END -> { stringProvider.getString(R.string.poll_end_room_list_preview) } - else -> { + in EventType.STATE_ROOM_BEACON_INFO -> { + stringProvider.getString(R.string.sent_live_location) + } + else -> { span { } } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt index a20c1e5f97..51dc26247c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/format/NoticeEventFormatter.kt @@ -21,10 +21,12 @@ import im.vector.app.R import im.vector.app.core.resources.StringProvider import im.vector.app.features.roomprofile.permissions.RoleFormatter import im.vector.app.features.settings.VectorPreferences +import org.matrix.android.sdk.api.crypto.MXCRYPTO_ALGORITHM_MEGOLM import org.matrix.android.sdk.api.extensions.appendNl import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptionEventContent import org.matrix.android.sdk.api.session.events.model.isThread import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.GuestAccess @@ -47,8 +49,6 @@ import org.matrix.android.sdk.api.session.room.model.create.RoomCreateContent import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.widgets.model.WidgetContent -import org.matrix.android.sdk.internal.crypto.MXCRYPTO_ALGORITHM_MEGOLM -import org.matrix.android.sdk.internal.crypto.model.event.EncryptionEventContent import timber.log.Timber import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/AudioMessagePlaybackTracker.kt similarity index 85% rename from vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt rename to vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/AudioMessagePlaybackTracker.kt index 8167ad94af..0312ac9e6f 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/VoiceMessagePlaybackTracker.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/AudioMessagePlaybackTracker.kt @@ -22,7 +22,7 @@ import javax.inject.Inject import javax.inject.Singleton @Singleton -class VoiceMessagePlaybackTracker @Inject constructor() { +class AudioMessagePlaybackTracker @Inject constructor() { private val mainHandler = Handler(Looper.getMainLooper()) private val listeners = mutableMapOf<String, Listener>() @@ -33,7 +33,7 @@ class VoiceMessagePlaybackTracker @Inject constructor() { activityListeners.add(listener) } - fun unTrackActivity(listener: ActivityListener) { + fun untrackActivity(listener: ActivityListener) { activityListeners.remove(listener) } @@ -46,10 +46,16 @@ class VoiceMessagePlaybackTracker @Inject constructor() { } } - fun unTrack(id: String) { + fun untrack(id: String) { listeners.remove(id) } + fun pauseAllPlaybacks() { + listeners.keys.forEach { key -> + pausePlayback(key) + } + } + fun makeAllPlaybacksIdle() { listeners.keys.forEach { key -> setState(key, Listener.State.Idle) @@ -87,19 +93,25 @@ class VoiceMessagePlaybackTracker @Inject constructor() { } fun pausePlayback(id: String) { - val currentPlaybackTime = getPlaybackTime(id) - val currentPercentage = getPercentage(id) - setState(id, Listener.State.Paused(currentPlaybackTime, currentPercentage)) + if (getPlaybackState(id) is Listener.State.Playing) { + val currentPlaybackTime = getPlaybackTime(id) + val currentPercentage = getPercentage(id) + setState(id, Listener.State.Paused(currentPlaybackTime, currentPercentage)) + } } fun stopPlayback(id: String) { setState(id, Listener.State.Idle) } - fun updateCurrentPlaybackTime(id: String, time: Int, percentage: Float) { + fun updatePlayingAtPlaybackTime(id: String, time: Int, percentage: Float) { setState(id, Listener.State.Playing(time, percentage)) } + fun updatePausedAtPlaybackTime(id: String, time: Int, percentage: Float) { + setState(id, Listener.State.Paused(time, percentage)) + } + fun updateCurrentRecording(id: String, amplitudeList: List<Int>) { setState(id, Listener.State.Recording(amplitudeList)) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt index 76fcbae96c..79897fdcb8 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/MessageInformationDataFactory.kt @@ -31,10 +31,11 @@ import im.vector.app.features.home.room.detail.timeline.item.SendStateDecoration import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayoutFactory import im.vector.app.features.settings.VectorPreferences import im.vector.app.features.themes.BubbleThemeUtils -import org.matrix.android.sdk.api.crypto.VerificationState import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.verification.VerificationState import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.EncryptedEventContent import org.matrix.android.sdk.api.session.events.model.isAttachmentMessage import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams @@ -46,7 +47,6 @@ import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent import org.matrix.android.sdk.api.session.room.timeline.hasBeenEdited -import org.matrix.android.sdk.internal.crypto.model.event.EncryptedEventContent import timber.log.Timber import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt index 96a2ca4609..1736b20d44 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/helper/TimelineDisplayableEvents.kt @@ -50,8 +50,8 @@ object TimelineDisplayableEvents { EventType.STATE_ROOM_TOMBSTONE, EventType.STATE_ROOM_JOIN_RULES, EventType.KEY_VERIFICATION_DONE, - EventType.KEY_VERIFICATION_CANCEL - ) + EventType.POLL_START + EventType.KEY_VERIFICATION_CANCEL, + ) + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO } fun TimelineEvent.canBeMerged(): Boolean { @@ -71,7 +71,7 @@ fun TimelineEvent.isRoomConfiguration(roomCreatorUserId: String?): Boolean { EventType.STATE_ROOM_CANONICAL_ALIAS, EventType.STATE_ROOM_POWER_LEVELS, EventType.STATE_ROOM_ENCRYPTION -> true - EventType.STATE_ROOM_MEMBER -> { + EventType.STATE_ROOM_MEMBER -> { // Keep only room member events regarding the room creator (when he joined the room), // but exclude events where the room creator invite others, or where others join roomCreatorUserId != null && root.stateKey == roomCreatorUserId diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/image/ImageContentRendererFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/image/ImageContentRendererFactory.kt index 2ad58df3b8..26cab4d863 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/image/ImageContentRendererFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/image/ImageContentRendererFactory.kt @@ -17,6 +17,7 @@ package im.vector.app.features.home.room.detail.timeline.image import im.vector.app.features.media.ImageContentRenderer +import org.matrix.android.sdk.api.session.crypto.attachments.toElementToDecrypt import org.matrix.android.sdk.api.session.events.model.isImageMessage import org.matrix.android.sdk.api.session.events.model.isVideoMessage import org.matrix.android.sdk.api.session.events.model.toModel @@ -25,7 +26,6 @@ import org.matrix.android.sdk.api.session.room.model.message.MessageVideoContent import org.matrix.android.sdk.api.session.room.model.message.getFileUrl import org.matrix.android.sdk.api.session.room.model.message.getThumbnailUrl import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent -import org.matrix.android.sdk.internal.crypto.attachments.toElementToDecrypt fun TimelineEvent.buildImageContentRendererData(maxHeight: Int): ImageContentRenderer.Data? { return when { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt index e99d1bc25e..1b48b35b82 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/AbsBaseMessageItem.kt @@ -44,7 +44,7 @@ import im.vector.app.features.home.room.detail.timeline.view.TimelineMessageLayo import im.vector.app.features.home.room.detail.timeline.view.scRenderMessageLayout import im.vector.app.features.reactions.widget.ReactionButton import im.vector.app.features.themes.ThemeUtils -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.room.send.SendState import kotlin.math.ceil diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt index a86bd5bb34..3125e71231 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MergedRoomCreationItem.kt @@ -134,7 +134,10 @@ abstract class MergedRoomCreationItem : BasedMergedItem<MergedRoomCreationItem.H val membersCount = roomSummary?.otherMemberIds?.size ?: 0 if (isDirect) { - holder.roomDescriptionText.text = holder.view.resources.getString(R.string.this_is_the_beginning_of_dm, roomSummary?.displayName ?: "") + holder.roomDescriptionText.text = holder.view.resources.getString( + R.string.this_is_the_beginning_of_dm, + distinctMergeData.lastOrNull()?.memberName ?: "" + ) } else if (roomDisplayName.isNullOrBlank() || roomSummary.name.isBlank()) { holder.roomDescriptionText.text = holder.view.resources.getString(R.string.this_is_the_beginning_of_room_no_name) } else { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageAudioItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageAudioItem.kt new file mode 100644 index 0000000000..3c071578cc --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageAudioItem.kt @@ -0,0 +1,213 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.detail.timeline.item + +import android.content.Context +import android.content.res.ColorStateList +import android.graphics.Color +import android.text.format.DateUtils +import android.view.ViewGroup +import android.widget.ImageButton +import android.widget.SeekBar +import android.widget.TextView +import androidx.core.view.isVisible +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import im.vector.app.R +import im.vector.app.core.epoxy.ClickListener +import im.vector.app.core.epoxy.onClick +import im.vector.app.core.utils.TextUtils +import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker +import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadStateTrackerBinder +import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder +import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayout +import im.vector.app.features.themes.ThemeUtils + +@EpoxyModelClass(layout = R.layout.item_timeline_event_base) +abstract class MessageAudioItem : AbsMessageItem<MessageAudioItem.Holder>() { + + @EpoxyAttribute + var filename: String = "" + + @EpoxyAttribute + var mxcUrl: String = "" + + @EpoxyAttribute + var duration: Int = 0 + + @EpoxyAttribute + var fileSize: Long = 0 + + @EpoxyAttribute + @JvmField + var isLocalFile = false + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var onSeek: ((percentage: Float) -> Unit)? = null + + @EpoxyAttribute + lateinit var contentUploadStateTrackerBinder: ContentUploadStateTrackerBinder + + @EpoxyAttribute + lateinit var contentDownloadStateTrackerBinder: ContentDownloadStateTrackerBinder + + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) + var playbackControlButtonClickListener: ClickListener? = null + + @EpoxyAttribute + lateinit var audioMessagePlaybackTracker: AudioMessagePlaybackTracker + + private var isUserSeeking = false + + override fun bind(holder: Holder) { + super.bind(holder) + renderSendState(holder.rootLayout, null) + bindViewAttributes(holder) + bindUploadState(holder) + applyLayoutTint(holder) + bindSeekBar(holder) + holder.audioPlaybackControlButton.setOnClickListener { playbackControlButtonClickListener?.invoke(it) } + renderStateBasedOnAudioPlayback(holder) + } + + private fun bindUploadState(holder: Holder) { + if (attributes.informationData.sendState.hasFailed()) { + holder.audioPlaybackControlButton.setImageResource(R.drawable.ic_cross) + holder.audioPlaybackControlButton.contentDescription = + holder.view.context.getString(R.string.error_audio_message_unable_to_play, filename) + holder.progressLayout.isVisible = false + } else { + contentUploadStateTrackerBinder.bind(attributes.informationData.eventId, isLocalFile, holder.progressLayout) + } + } + + private fun applyLayoutTint(holder: Holder) { + val backgroundTint = if (attributes.informationData.messageLayout is TimelineMessageLayout.Bubble) { + Color.TRANSPARENT + } else { + ThemeUtils.getColor(holder.view.context, R.attr.vctr_content_quinary) + } + holder.mainLayout.backgroundTintList = ColorStateList.valueOf(backgroundTint) + } + + private fun bindViewAttributes(holder: Holder) { + val formattedDuration = formatPlaybackTime(duration) + val formattedFileSize = TextUtils.formatFileSize(holder.rootLayout.context, fileSize, true) + val durationContentDescription = getPlaybackTimeContentDescription(holder.rootLayout.context, duration) + + holder.filenameView.text = filename + holder.filenameView.onClick(attributes.itemClickListener) + holder.audioPlaybackDuration.text = formattedDuration + holder.fileSize.text = holder.rootLayout.context.getString( + R.string.audio_message_file_size, formattedFileSize + ) + holder.mainLayout.contentDescription = holder.rootLayout.context.getString( + R.string.a11y_audio_message_item, filename, durationContentDescription, formattedFileSize + ) + } + + private fun bindSeekBar(holder: Holder) { + holder.audioSeekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { + override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { + holder.audioPlaybackTime.text = formatPlaybackTime( + (duration * (progress.toFloat() / 100)).toInt() + ) + } + override fun onStartTrackingTouch(seekBar: SeekBar) { + isUserSeeking = true + } + override fun onStopTrackingTouch(seekBar: SeekBar) { + isUserSeeking = false + val percentage = seekBar.progress.toFloat() / 100 + onSeek?.invoke(percentage) + } + }) + } + + private fun renderStateBasedOnAudioPlayback(holder: Holder) { + audioMessagePlaybackTracker.track(attributes.informationData.eventId, object : AudioMessagePlaybackTracker.Listener { + override fun onUpdate(state: AudioMessagePlaybackTracker.Listener.State) { + when (state) { + is AudioMessagePlaybackTracker.Listener.State.Idle -> renderIdleState(holder) + is AudioMessagePlaybackTracker.Listener.State.Playing -> renderPlayingState(holder, state) + is AudioMessagePlaybackTracker.Listener.State.Paused -> renderPausedState(holder, state) + is AudioMessagePlaybackTracker.Listener.State.Recording -> Unit + } + } + }) + } + + private fun renderIdleState(holder: Holder) { + holder.audioPlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play) + holder.audioPlaybackControlButton.contentDescription = + holder.view.context.getString(R.string.a11y_play_audio_message, filename) + holder.audioPlaybackTime.text = formatPlaybackTime(duration) + holder.audioSeekBar.progress = 0 + } + + private fun renderPlayingState(holder: Holder, state: AudioMessagePlaybackTracker.Listener.State.Playing) { + holder.audioPlaybackControlButton.setImageResource(R.drawable.ic_play_pause_pause) + holder.audioPlaybackControlButton.contentDescription = + holder.view.context.getString(R.string.a11y_pause_audio_message, filename) + + if (!isUserSeeking) { + holder.audioPlaybackTime.text = formatPlaybackTime(state.playbackTime) + holder.audioSeekBar.progress = (state.percentage * 100).toInt() + } + } + + private fun renderPausedState(holder: Holder, state: AudioMessagePlaybackTracker.Listener.State.Paused) { + holder.audioPlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play) + holder.audioPlaybackControlButton.contentDescription = + holder.view.context.getString(R.string.a11y_play_audio_message, filename) + holder.audioPlaybackTime.text = formatPlaybackTime(state.playbackTime) + holder.audioSeekBar.progress = (state.percentage * 100).toInt() + } + + private fun formatPlaybackTime(time: Int) = DateUtils.formatElapsedTime((time / 1000).toLong()) + + private fun getPlaybackTimeContentDescription(context: Context, time: Int): String { + val formattedPlaybackTime = formatPlaybackTime(time) + val (minutes, seconds) = formattedPlaybackTime.split(":").map { it.toIntOrNull() ?: 0 } + return context.getString(R.string.a11y_audio_playback_duration, minutes, seconds) + } + + override fun unbind(holder: Holder) { + super.unbind(holder) + contentUploadStateTrackerBinder.unbind(attributes.informationData.eventId) + contentDownloadStateTrackerBinder.unbind(mxcUrl) + audioMessagePlaybackTracker.untrack(attributes.informationData.eventId) + } + + override fun getViewStubId() = STUB_ID + + class Holder : AbsMessageItem.Holder(STUB_ID) { + val rootLayout by bind<ViewGroup>(R.id.messageRootLayout) + val mainLayout by bind<ViewGroup>(R.id.messageMainInnerLayout) + val filenameView by bind<TextView>(R.id.messageFilenameView) + val audioPlaybackControlButton by bind<ImageButton>(R.id.audioPlaybackControlButton) + val audioPlaybackTime by bind<TextView>(R.id.audioPlaybackTime) + val progressLayout by bind<ViewGroup>(R.id.messageFileUploadProgressLayout) + val fileSize by bind<TextView>(R.id.fileSize) + val audioPlaybackDuration by bind<TextView>(R.id.audioPlaybackDuration) + val audioSeekBar by bind<SeekBar>(R.id.audioSeekBar) + } + + companion object { + private const val STUB_ID = R.id.messageContentAudioStub + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageFileItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageFileItem.kt index cf8cf1af0e..ca46c643d2 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageFileItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageFileItem.kt @@ -50,14 +50,13 @@ abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() { @DrawableRes var iconRes: Int = 0 -// @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) -// var clickListener: ClickListener? = null + @EpoxyAttribute + @JvmField + var isLocalFile = false @EpoxyAttribute - var izLocalFile = false - - @EpoxyAttribute - var izDownloaded = false + @JvmField + var isDownloaded = false @EpoxyAttribute lateinit var contentUploadStateTrackerBinder: ContentUploadStateTrackerBinder @@ -68,17 +67,20 @@ abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() { override fun bind(holder: Holder) { super.bind(holder) renderSendState(holder.fileLayout, holder.filenameView) + if (!attributes.informationData.sendState.hasFailed()) { - contentUploadStateTrackerBinder.bind(attributes.informationData.eventId, izLocalFile, holder.progressLayout) + contentUploadStateTrackerBinder.bind(attributes.informationData.eventId, isLocalFile, holder.progressLayout) } else { holder.fileImageView.setImageResource(R.drawable.ic_cross) holder.progressLayout.isVisible = false } + holder.filenameView.text = filename + if (attributes.informationData.sendState.isSending()) { holder.fileImageView.setImageResource(iconRes) } else { - if (izDownloaded) { + if (isDownloaded) { holder.fileImageView.setImageResource(iconRes) holder.fileDownloadProgress.progress = 0 } else { @@ -86,7 +88,7 @@ abstract class MessageFileItem : AbsMessageItem<MessageFileItem.Holder>() { holder.fileImageView.setImageResource(R.drawable.ic_download) } } -// holder.view.setOnClickListener(clickListener) + val backgroundTint = if (attributes.informationData.messageLayout is TimelineMessageLayout.Bubble || attributes.informationData.messageLayout is TimelineMessageLayout.ScBubble) { Color.TRANSPARENT diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageInformationData.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageInformationData.kt index 9d01c65a10..8702607ada 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageInformationData.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageInformationData.kt @@ -19,7 +19,7 @@ package im.vector.app.features.home.room.detail.timeline.item import android.os.Parcelable import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayout import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.api.crypto.VerificationState +import org.matrix.android.sdk.api.session.crypto.verification.VerificationState import org.matrix.android.sdk.api.session.room.send.SendState import org.matrix.android.sdk.api.util.MatrixItem diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageLiveLocationStartItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageLiveLocationStartItem.kt new file mode 100644 index 0000000000..390db0ef50 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageLiveLocationStartItem.kt @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.home.room.detail.timeline.item + +import android.graphics.drawable.ColorDrawable +import android.widget.ImageView +import androidx.core.view.updateLayoutParams +import com.airbnb.epoxy.EpoxyAttribute +import com.airbnb.epoxy.EpoxyModelClass +import com.bumptech.glide.load.resource.bitmap.GranularRoundedCorners +import com.bumptech.glide.load.resource.bitmap.RoundedCorners +import im.vector.app.R +import im.vector.app.core.glide.GlideApp +import im.vector.app.core.utils.DimensionConverter +import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayout +import im.vector.app.features.home.room.detail.timeline.style.granularRoundedCorners +import im.vector.app.features.themes.ThemeUtils + +@EpoxyModelClass(layout = R.layout.item_timeline_event_base) +abstract class MessageLiveLocationStartItem : AbsMessageItem<MessageLiveLocationStartItem.Holder>() { + + @EpoxyAttribute + var mapWidth: Int = 0 + + @EpoxyAttribute + var mapHeight: Int = 0 + + override fun bind(holder: Holder) { + super.bind(holder) + renderSendState(holder.view, null) + bindMap(holder) + bindBottomBanner(holder) + } + + private fun bindMap(holder: Holder) { + val messageLayout = attributes.informationData.messageLayout + val mapCornerTransformation = if (messageLayout is TimelineMessageLayout.Bubble) { + messageLayout.cornersRadius.granularRoundedCorners() + } else { + RoundedCorners(getDefaultLayoutCornerRadiusInDp(holder)) + } + holder.noLocationMapImageView.updateLayoutParams { + width = mapWidth + height = mapHeight + } + GlideApp.with(holder.noLocationMapImageView) + .load(R.drawable.bg_no_location_map) + .transform(mapCornerTransformation) + .into(holder.noLocationMapImageView) + } + + private fun bindBottomBanner(holder: Holder) { + val messageLayout = attributes.informationData.messageLayout + val imageCornerTransformation = if (messageLayout is TimelineMessageLayout.Bubble) { + GranularRoundedCorners(0f, 0f, messageLayout.cornersRadius.bottomEndRadius, messageLayout.cornersRadius.bottomStartRadius) + } else { + val bottomCornerRadius = getDefaultLayoutCornerRadiusInDp(holder).toFloat() + GranularRoundedCorners(0f, 0f, bottomCornerRadius, bottomCornerRadius) + } + GlideApp.with(holder.bannerImageView) + .load(ColorDrawable(ThemeUtils.getColor(holder.bannerImageView.context, R.attr.colorSurface))) + .transform(imageCornerTransformation) + .into(holder.bannerImageView) + } + + private fun getDefaultLayoutCornerRadiusInDp(holder: Holder): Int { + val dimensionConverter = DimensionConverter(holder.view.resources) + return dimensionConverter.dpToPx(8) + } + + override fun getViewStubId() = STUB_ID + + class Holder : AbsMessageItem.Holder(STUB_ID) { + val bannerImageView by bind<ImageView>(R.id.locationLiveStartBanner) + val noLocationMapImageView by bind<ImageView>(R.id.locationLiveStartMap) + } + + companion object { + private const val STUB_ID = R.id.messageContentLiveLocationStartStub + } +} diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt index d4cf220ecb..02c8853922 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/MessageVoiceItem.kt @@ -32,9 +32,9 @@ import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.app.R import im.vector.app.core.epoxy.ClickListener +import im.vector.app.features.home.room.detail.timeline.helper.AudioMessagePlaybackTracker import im.vector.app.features.home.room.detail.timeline.helper.ContentDownloadStateTrackerBinder import im.vector.app.features.home.room.detail.timeline.helper.ContentUploadStateTrackerBinder -import im.vector.app.features.home.room.detail.timeline.helper.VoiceMessagePlaybackTracker import im.vector.app.features.home.room.detail.timeline.style.TimelineMessageLayout import im.vector.app.features.themes.ThemeUtils import im.vector.app.features.voice.AudioWaveformView @@ -57,10 +57,8 @@ abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() { var waveform: List<Int> = emptyList() @EpoxyAttribute - var izLocalFile = false - - @EpoxyAttribute - var izDownloaded = false + @JvmField + var isLocalFile = false @EpoxyAttribute var filename: CharSequence? = null @@ -78,13 +76,13 @@ abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() { var waveformTouchListener: WaveformTouchListener? = null @EpoxyAttribute - lateinit var voiceMessagePlaybackTracker: VoiceMessagePlaybackTracker + lateinit var audioMessagePlaybackTracker: AudioMessagePlaybackTracker override fun bind(holder: Holder) { super.bind(holder) renderSendState(holder.voiceLayout, null) if (!attributes.informationData.sendState.hasFailed()) { - contentUploadStateTrackerBinder.bind(attributes.informationData.eventId, izLocalFile, holder.progressLayout) + contentUploadStateTrackerBinder.bind(attributes.informationData.eventId, isLocalFile, holder.progressLayout) } else { holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_cross) holder.voicePlaybackControlButton.contentDescription = holder.view.context.getString(R.string.error_voice_message_unable_to_play) @@ -103,11 +101,11 @@ abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() { ThemeUtils.getColor(holder.view.context, R.attr.sc_message_bg_incoming) } holder.voicePlaybackLayout.backgroundTintList = ColorStateList.valueOf(backgroundTint) - holder.voicePlaybackControlButton.setOnClickListener { playbackControlButtonClickListener?.invoke(it) } } private fun onWaveformViewReady(holder: Holder) { holder.voicePlaybackWaveform.setOnLongClickListener(attributes.itemLongClickListener) + holder.voicePlaybackControlButton.setOnClickListener { playbackControlButtonClickListener?.invoke(it) } val waveformColorIdle = ThemeUtils.getColor(holder.view.context, R.attr.vctr_content_quaternary) val waveformColorPlayed = ThemeUtils.getColor(holder.view.context, R.attr.vctr_content_secondary) @@ -142,13 +140,13 @@ abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() { true } - voiceMessagePlaybackTracker.track(attributes.informationData.eventId, object : VoiceMessagePlaybackTracker.Listener { - override fun onUpdate(state: VoiceMessagePlaybackTracker.Listener.State) { + audioMessagePlaybackTracker.track(attributes.informationData.eventId, object : AudioMessagePlaybackTracker.Listener { + override fun onUpdate(state: AudioMessagePlaybackTracker.Listener.State) { when (state) { - is VoiceMessagePlaybackTracker.Listener.State.Idle -> renderIdleState(holder, waveformColorIdle, waveformColorPlayed) - is VoiceMessagePlaybackTracker.Listener.State.Playing -> renderPlayingState(holder, state, waveformColorIdle, waveformColorPlayed) - is VoiceMessagePlaybackTracker.Listener.State.Paused -> renderPausedState(holder, state, waveformColorIdle, waveformColorPlayed) - is VoiceMessagePlaybackTracker.Listener.State.Recording -> Unit + is AudioMessagePlaybackTracker.Listener.State.Idle -> renderIdleState(holder, waveformColorIdle, waveformColorPlayed) + is AudioMessagePlaybackTracker.Listener.State.Playing -> renderPlayingState(holder, state, waveformColorIdle, waveformColorPlayed) + is AudioMessagePlaybackTracker.Listener.State.Paused -> renderPausedState(holder, state, waveformColorIdle, waveformColorPlayed) + is AudioMessagePlaybackTracker.Listener.State.Recording -> Unit } } }) @@ -163,14 +161,14 @@ abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() { holder.voicePlaybackWaveform.updateColors(0f, playedColor, idleColor) } - private fun renderPlayingState(holder: Holder, state: VoiceMessagePlaybackTracker.Listener.State.Playing, idleColor: Int, playedColor: Int) { + private fun renderPlayingState(holder: Holder, state: AudioMessagePlaybackTracker.Listener.State.Playing, idleColor: Int, playedColor: Int) { holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_pause) holder.voicePlaybackControlButton.contentDescription = holder.view.context.getString(R.string.a11y_pause_voice_message) holder.voicePlaybackTime.text = formatPlaybackTime(state.playbackTime) holder.voicePlaybackWaveform.updateColors(state.percentage, playedColor, idleColor) } - private fun renderPausedState(holder: Holder, state: VoiceMessagePlaybackTracker.Listener.State.Paused, idleColor: Int, playedColor: Int) { + private fun renderPausedState(holder: Holder, state: AudioMessagePlaybackTracker.Listener.State.Paused, idleColor: Int, playedColor: Int) { holder.voicePlaybackControlButton.setImageResource(R.drawable.ic_play_pause_play) holder.voicePlaybackControlButton.contentDescription = holder.view.context.getString(R.string.a11y_play_voice_message) holder.voicePlaybackTime.text = formatPlaybackTime(state.playbackTime) @@ -183,7 +181,7 @@ abstract class MessageVoiceItem : AbsMessageItem<MessageVoiceItem.Holder>() { super.unbind(holder) contentUploadStateTrackerBinder.unbind(attributes.informationData.eventId) contentDownloadStateTrackerBinder.unbind(mxcUrl) - voiceMessagePlaybackTracker.unTrack(attributes.informationData.eventId) + audioMessagePlaybackTracker.untrack(attributes.informationData.eventId) } override fun applyScBubbleStyle(messageLayout: TimelineMessageLayout.ScBubble, holder: Holder) { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/NoticeItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/NoticeItem.kt index f4626ceac3..3f3598471d 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/NoticeItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/NoticeItem.kt @@ -30,7 +30,7 @@ import im.vector.app.features.home.room.detail.timeline.TimelineEventController import im.vector.app.features.home.room.detail.timeline.view.TimelineMessageLayoutRenderer import im.vector.app.features.home.room.detail.timeline.view.scOnlyRenderMessageLayout import im.vector.lib.core.utils.epoxy.charsequence.EpoxyCharSequence -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel @EpoxyModelClass(layout = R.layout.item_timeline_event_base_noinfo) abstract class NoticeItem : BaseEventItem<NoticeItem.Holder>() { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/VerificationRequestItem.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/VerificationRequestItem.kt index 61fcddd123..0e6530fdca 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/VerificationRequestItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/item/VerificationRequestItem.kt @@ -35,8 +35,8 @@ import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.RoomDetailAction import im.vector.app.features.home.room.detail.timeline.MessageColorProvider import im.vector.app.features.home.room.detail.timeline.TimelineEventController -import org.matrix.android.sdk.api.crypto.VerificationState import org.matrix.android.sdk.api.session.crypto.verification.VerificationService +import org.matrix.android.sdk.api.session.crypto.verification.VerificationState @EpoxyModelClass(layout = R.layout.item_timeline_event_base_state) abstract class VerificationRequestItem : AbsBaseMessageItem<VerificationRequestItem.Holder>() { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayout.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayout.kt index 475ae2e099..d0c9ba7c47 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayout.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayout.kt @@ -42,20 +42,21 @@ sealed interface TimelineMessageLayout : Parcelable { @Parcelize data class Bubble( - override val showAvatar: Boolean, - override val showDisplayName: Boolean, - override val showTimestamp: Boolean = true, - override val showE2eDecoration: Boolean = true, - val addTopMargin: Boolean = false, - val isIncoming: Boolean, - val isPseudoBubble: Boolean, - val cornersRadius: CornersRadius, - val timestampAsOverlay: Boolean, - override val layoutRes: Int = if (isIncoming) { - R.layout.item_timeline_event_bubble_incoming_base - } else { - R.layout.item_timeline_event_bubble_outgoing_base - }, + override val showAvatar: Boolean, + override val showDisplayName: Boolean, + override val showTimestamp: Boolean = true, + override val showE2eDecoration: Boolean = true, + val addTopMargin: Boolean = false, + val isIncoming: Boolean, + val isPseudoBubble: Boolean, + val cornersRadius: CornersRadius, + val timestampInsideMessage: Boolean, + val addMessageOverlay: Boolean, + override val layoutRes: Int = if (isIncoming) { + R.layout.item_timeline_event_bubble_incoming_base + } else { + R.layout.item_timeline_event_bubble_outgoing_base + }, ) : TimelineMessageLayout { @Parcelize diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayoutFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayoutFactory.kt index 944540e88e..e159c9afc9 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayoutFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/style/TimelineMessageLayoutFactory.kt @@ -49,7 +49,7 @@ class TimelineMessageLayoutFactory @Inject constructor(private val session: Sess EventType.MESSAGE, EventType.ENCRYPTED, EventType.STICKER - ) + EventType.POLL_START + ) + EventType.POLL_START + EventType.STATE_ROOM_BEACON_INFO // Can't be rendered in bubbles, so get back to default layout private val MSG_TYPES_WITHOUT_BUBBLE_LAYOUT = setOf( @@ -61,10 +61,13 @@ class TimelineMessageLayoutFactory @Inject constructor(private val session: Sess MessageType.MSGTYPE_IMAGE, MessageType.MSGTYPE_VIDEO, MessageType.MSGTYPE_STICKER_LOCAL, - //MessageType.MSGTYPE_EMOTE + //MessageType.MSGTYPE_EMOTE, + MessageType.MSGTYPE_LIVE_LOCATION_STATE, ) - private val MSG_TYPES_WITH_TIMESTAMP_AS_OVERLAY = setOf( - MessageType.MSGTYPE_IMAGE, MessageType.MSGTYPE_VIDEO + private val MSG_TYPES_WITH_TIMESTAMP_INSIDE_MESSAGE = setOf( + MessageType.MSGTYPE_IMAGE, + MessageType.MSGTYPE_VIDEO, + MessageType.MSGTYPE_LIVE_LOCATION_STATE, ) } @@ -73,7 +76,7 @@ class TimelineMessageLayoutFactory @Inject constructor(private val session: Sess } private val isRTL: Boolean by lazy { - localeProvider.isRTL() + localeProvider.isRTL() } fun create(params: TimelineItemFactoryParams): TimelineMessageLayout { @@ -123,7 +126,7 @@ class TimelineMessageLayoutFactory @Inject constructor(private val session: Sess singleSidedLayout = singleSidedLayout, isRealBubble = isBubble && !pseudoBubble, isPseudoBubble = pseudoBubble, - timestampAsOverlay = messageContent.timestampAsOverlay() + timestampAsOverlay = messageContent.timestampInsideMessage() ) } } @@ -154,7 +157,8 @@ class TimelineMessageLayoutFactory @Inject constructor(private val session: Sess isIncoming = !isSentByMe, cornersRadius = cornersRadius, isPseudoBubble = messageContent.isPseudoBubble(event), - timestampAsOverlay = messageContent.timestampAsOverlay() + timestampInsideMessage = messageContent.timestampInsideMessage(), + addMessageOverlay = messageContent.shouldAddMessageOverlay(), ) } else { buildModernLayout(showInformation) @@ -206,10 +210,18 @@ class TimelineMessageLayoutFactory @Inject constructor(private val session: Sess return msgType == MessageType.MSGTYPE_EMOTE } - private fun MessageContent?.timestampAsOverlay(): Boolean { + private fun MessageContent?.timestampInsideMessage(): Boolean { if (this == null) return false if (msgType == MessageType.MSGTYPE_LOCATION) return vectorPreferences.labsRenderLocationsInTimeline() - return this.msgType in MSG_TYPES_WITH_TIMESTAMP_AS_OVERLAY + return this.msgType in MSG_TYPES_WITH_TIMESTAMP_INSIDE_MESSAGE + } + + private fun MessageContent?.shouldAddMessageOverlay(): Boolean { + return when { + this == null || msgType == MessageType.MSGTYPE_LIVE_LOCATION_STATE -> false + msgType == MessageType.MSGTYPE_LOCATION -> vectorPreferences.labsRenderLocationsInTimeline() + else -> msgType in MSG_TYPES_WITH_TIMESTAMP_INSIDE_MESSAGE + } } private fun TimelineEvent.shouldBuildBubbleLayout(): Boolean { diff --git a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt index 023fd03969..6169875bc7 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/detail/timeline/view/MessageBubbleView.kt @@ -45,9 +45,9 @@ import im.vector.app.features.themes.ThemeUtils import timber.log.Timber class MessageBubbleView @JvmOverloads constructor( - context: Context, - attrs: AttributeSet? = null, - defStyleAttr: Int = 0, + context: Context, + attrs: AttributeSet? = null, + defStyleAttr: Int = 0, ) : RelativeLayout(context, attrs, defStyleAttr), TimelineMessageLayoutRenderer { private var isIncoming: Boolean = false @@ -91,21 +91,21 @@ class MessageBubbleView @JvmOverloads constructor( outlineProvider = ViewOutlineProvider.BACKGROUND clipToOutline = true background = RippleDrawable( - ContextCompat.getColorStateList(context, R.color.mtrl_btn_ripple_color) ?: ColorStateList.valueOf(Color.TRANSPARENT), - bubbleDrawable, - rippleMaskDrawable) + ContextCompat.getColorStateList(context, R.color.mtrl_btn_ripple_color) ?: ColorStateList.valueOf(Color.TRANSPARENT), + bubbleDrawable, + rippleMaskDrawable) } } override fun <H: BaseEventItem.BaseHolder>renderMessageLayout(messageLayout: TimelineMessageLayout, bubbleDependentView: BubbleDependentView<H>, holder: H) { (messageLayout as? TimelineMessageLayout.Bubble) - ?.updateDrawables() - ?.setConstraintsAndColor() - ?.toggleMessageOverlay() - ?.setPadding() - ?.setMargins() - ?.setAdditionalTopSpace() - ?: Timber.v("Can't render messageLayout $messageLayout") + ?.updateDrawables() + ?.setConstraints() + ?.toggleMessageOverlay() + ?.setPadding() + ?.setMargins() + ?.setAdditionalTopSpace() + ?: Timber.v("Can't render messageLayout $messageLayout") } private fun TimelineMessageLayout.Bubble.updateDrawables() = apply { @@ -123,17 +123,13 @@ class MessageBubbleView @JvmOverloads constructor( rippleMaskDrawable.shapeAppearanceModel = shapeAppearanceModel } - private fun TimelineMessageLayout.Bubble.setConstraintsAndColor() = apply { + private fun TimelineMessageLayout.Bubble.setConstraints() = apply { ConstraintSet().apply { clone(views.bubbleView) clear(R.id.viewStubContainer, ConstraintSet.END) - if (timestampAsOverlay) { - val timeColor = ContextCompat.getColor(context, R.color.palette_white) - views.messageTimeView.setTextColor(timeColor) + if (timestampInsideMessage) { connect(R.id.viewStubContainer, ConstraintSet.END, R.id.parent, ConstraintSet.END, 0) } else { - val timeColor = ThemeUtils.getColor(context, R.attr.vctr_content_tertiary) - views.messageTimeView.setTextColor(timeColor) connect(R.id.viewStubContainer, ConstraintSet.END, R.id.messageTimeView, ConstraintSet.START, 0) } applyTo(views.bubbleView) @@ -141,16 +137,20 @@ class MessageBubbleView @JvmOverloads constructor( } private fun TimelineMessageLayout.Bubble.toggleMessageOverlay() = apply { - if (timestampAsOverlay) { + if (addMessageOverlay) { + val timeColor = ContextCompat.getColor(context, R.color.palette_white) + views.messageTimeView.setTextColor(timeColor) views.messageOverlayView.isVisible = true (views.messageOverlayView.background as? GradientDrawable)?.cornerRadii = cornersRadius.toFloatArray() } else { + val timeColor = ThemeUtils.getColor(context, R.attr.vctr_content_tertiary) + views.messageTimeView.setTextColor(timeColor) views.messageOverlayView.isVisible = false } } private fun TimelineMessageLayout.Bubble.setPadding() = apply { - if (isPseudoBubble && timestampAsOverlay) { + if (isPseudoBubble && timestampInsideMessage) { views.viewStubContainer.root.setPadding(0, 0, 0, 0) } else { views.viewStubContainer.root.setPadding(horizontalStubPadding, verticalStubPadding, horizontalStubPadding, verticalStubPadding) diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt index e8c259bf46..f3bd4906db 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItem.kt @@ -38,7 +38,7 @@ import im.vector.app.features.displayname.getBestName import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.themes.ThemeUtils import im.vector.lib.core.utils.epoxy.charsequence.EpoxyCharSequence -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.presence.model.UserPresence import org.matrix.android.sdk.api.util.MatrixItem diff --git a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt index ae8a71ed24..5cd3cf156c 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/list/RoomSummaryItemFactory.kt @@ -29,7 +29,6 @@ import im.vector.app.features.home.AvatarRenderer import im.vector.app.features.home.room.detail.timeline.format.DisplayableEventFormatter import im.vector.app.features.home.room.typing.TypingHelper import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence -import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.session.room.members.ChangeMembershipState import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.model.RoomSummary @@ -42,8 +41,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor private val stringProvider: StringProvider, private val typingHelper: TypingHelper, private val avatarRenderer: AvatarRenderer, - private val errorFormatter: ErrorFormatter, - private val matrixConfiguration: MatrixConfiguration) { + private val errorFormatter: ErrorFormatter) { fun create(roomSummary: RoomSummary, roomChangeMembershipStates: Map<String, ChangeMembershipState>, @@ -127,7 +125,7 @@ class RoomSummaryItemFactory @Inject constructor(private val displayableEventFor // We do not display shield in the room list anymore // .encryptionTrustLevel(roomSummary.roomEncryptionTrustLevel) .izPublic(roomSummary.isPublic) - .showPresence(roomSummary.isDirect && matrixConfiguration.presenceSyncEnabled) + .showPresence(roomSummary.isDirect) .userPresence(roomSummary.directUserPresence) .matrixItem(roomSummary.toMatrixItem()) .lastEventTime(latestEventTime) diff --git a/vector/src/main/java/im/vector/app/features/home/room/threads/ThreadsManager.kt b/vector/src/main/java/im/vector/app/features/home/room/threads/ThreadsManager.kt index 469a12019a..545077b550 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/threads/ThreadsManager.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/threads/ThreadsManager.kt @@ -18,13 +18,14 @@ package im.vector.app.features.home.room.threads import android.app.Activity import android.text.Spanned +import androidx.annotation.StringRes import androidx.core.text.HtmlCompat import im.vector.app.R import im.vector.app.core.resources.StringProvider import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs import im.vector.app.features.settings.VectorPreferences -import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import javax.inject.Inject /** @@ -49,11 +50,17 @@ class ThreadsManager @Inject constructor( /** * Generates and return an Html spanned string to be rendered especially in dialogs */ - fun getBetaEnableThreadsMessage(): Spanned { + private fun generateLearnMoreHtmlString(@StringRes messageId: Int): Spanned { val learnMore = stringProvider.getString(R.string.action_learn_more) val learnMoreUrl = stringProvider.getString(R.string.threads_learn_more_url) val href = "<a href='$learnMoreUrl'>$learnMore</a>.<br><br>" - val message = stringProvider.getString(R.string.threads_beta_enable_notice_message, href) + val message = stringProvider.getString(messageId, href) return HtmlCompat.fromHtml(message, HtmlCompat.FROM_HTML_MODE_LEGACY) } + + fun getBetaEnableThreadsMessage(): Spanned = + generateLearnMoreHtmlString(R.string.threads_beta_enable_notice_message) + + fun getLabsEnableThreadsMessage(): Spanned = + generateLearnMoreHtmlString(R.string.threads_labs_enable_notice_message) } diff --git a/vector/src/main/java/im/vector/app/features/home/room/threads/arguments/ThreadListArgs.kt b/vector/src/main/java/im/vector/app/features/home/room/threads/arguments/ThreadListArgs.kt index aa3746ea41..febd063202 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/threads/arguments/ThreadListArgs.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/threads/arguments/ThreadListArgs.kt @@ -18,7 +18,7 @@ package im.vector.app.features.home.room.threads.arguments import android.os.Parcelable import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel @Parcelize data class ThreadListArgs( diff --git a/vector/src/main/java/im/vector/app/features/home/room/threads/arguments/ThreadTimelineArgs.kt b/vector/src/main/java/im/vector/app/features/home/room/threads/arguments/ThreadTimelineArgs.kt index d3a80811ea..19419e52de 100644 --- a/vector/src/main/java/im/vector/app/features/home/room/threads/arguments/ThreadTimelineArgs.kt +++ b/vector/src/main/java/im/vector/app/features/home/room/threads/arguments/ThreadTimelineArgs.kt @@ -18,7 +18,7 @@ package im.vector.app.features.home.room.threads.arguments import android.os.Parcelable import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel @Parcelize data class ThreadTimelineArgs( diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingService.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingService.kt index 063cc3caa6..2126cdac04 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingService.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingService.kt @@ -29,7 +29,7 @@ import im.vector.app.features.session.coroutineScope import kotlinx.coroutines.launch import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.events.model.EventType.generateBeaconInfoStateEventType +import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toContent import org.matrix.android.sdk.api.session.room.model.livelocation.BeaconInfo import org.matrix.android.sdk.api.session.room.model.livelocation.LiveLocationBeaconContent @@ -87,7 +87,7 @@ class LocationSharingService : VectorService(), LocationTracker.Callback { .getSafeActiveSession() ?.let { session -> session.coroutineScope.launch(session.coroutineDispatchers.io) { - sendBeaconInfo(session, roomArgs) + sendLiveBeaconInfo(session, roomArgs) } } } @@ -95,7 +95,7 @@ class LocationSharingService : VectorService(), LocationTracker.Callback { return START_STICKY } - private suspend fun sendBeaconInfo(session: Session, roomArgs: RoomArgs) { + private suspend fun sendLiveBeaconInfo(session: Session, roomArgs: RoomArgs) { val beaconContent = LiveLocationBeaconContent( unstableBeaconInfo = BeaconInfo( timeout = roomArgs.durationMillis, @@ -104,12 +104,11 @@ class LocationSharingService : VectorService(), LocationTracker.Callback { unstableTimestampAsMilliseconds = clock.epochMillis() ).toContent() - val eventType = generateBeaconInfoStateEventType(session.myUserId) val stateKey = session.myUserId session .getRoom(roomArgs.roomId) ?.sendStateEvent( - eventType = eventType, + eventType = EventType.STATE_ROOM_BEACON_INFO.first(), stateKey = stateKey, body = beaconContent ) @@ -130,8 +129,12 @@ class LocationSharingService : VectorService(), LocationTracker.Callback { } } - private fun stopSharingLocation(roomId: String) { + fun stopSharingLocation(roomId: String) { Timber.i("### LocationSharingService.stopSharingLocation for $roomId") + + // Send a new beacon info state by setting live field as false + sendStoppedBeaconInfo(roomId) + synchronized(roomArgsList) { roomArgsList.removeAll { it.roomId == roomId } if (roomArgsList.isEmpty()) { @@ -141,8 +144,48 @@ class LocationSharingService : VectorService(), LocationTracker.Callback { } } + private fun sendStoppedBeaconInfo(roomId: String) { + activeSessionHolder + .getSafeActiveSession() + ?.let { session -> + session.coroutineScope.launch(session.coroutineDispatchers.io) { + session.getRoom(roomId)?.stopLiveLocation(session.myUserId) + } + } + } + override fun onLocationUpdate(locationData: LocationData) { Timber.i("### LocationSharingService.onLocationUpdate. Uncertainty: ${locationData.uncertainty}") + + val session = activeSessionHolder.getSafeActiveSession() + // Emit location update to all rooms in which live location sharing is active + session?.coroutineScope?.launch(session.coroutineDispatchers.io) { + roomArgsList.toList().forEach { roomArg -> + sendLiveLocation(roomArg.roomId, locationData) + } + } + } + + private suspend fun sendLiveLocation(roomId: String, locationData: LocationData) { + val session = activeSessionHolder.getSafeActiveSession() + val room = session?.getRoom(roomId) + val userId = session?.myUserId + + if (room == null || userId == null) { + return + } + + room + .getLiveLocationBeaconInfo(userId, true) + ?.eventId + ?.let { + room.sendLiveLocation( + beaconInfoEventId = it, + latitude = locationData.latitude, + longitude = locationData.longitude, + uncertainty = locationData.uncertainty + ) + } } override fun onLocationProviderIsNotAvailable() { diff --git a/vector/src/main/java/im/vector/app/features/location/LocationSharingServiceConnection.kt b/vector/src/main/java/im/vector/app/features/location/LocationSharingServiceConnection.kt index 9af6b1539a..e72f77531b 100644 --- a/vector/src/main/java/im/vector/app/features/location/LocationSharingServiceConnection.kt +++ b/vector/src/main/java/im/vector/app/features/location/LocationSharingServiceConnection.kt @@ -34,6 +34,7 @@ class LocationSharingServiceConnection @Inject constructor( private var callback: Callback? = null private var isBound = false + private var locationSharingService: LocationSharingService? = null fun bind(callback: Callback) { this.callback = callback @@ -51,13 +52,19 @@ class LocationSharingServiceConnection @Inject constructor( callback = null } + fun stopLiveLocationSharing(roomId: String) { + locationSharingService?.stopSharingLocation(roomId) + } + override fun onServiceConnected(className: ComponentName, binder: IBinder) { + locationSharingService = (binder as LocationSharingService.LocalBinder).getService() isBound = true callback?.onLocationServiceRunning() } override fun onServiceDisconnected(className: ComponentName) { isBound = false + locationSharingService = null callback?.onLocationServiceStopped() } } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginAction.kt b/vector/src/main/java/im/vector/app/features/login/LoginAction.kt index 70ca49a10e..800df32b9d 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginAction.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginAction.kt @@ -20,7 +20,7 @@ import im.vector.app.core.platform.VectorViewModelAction import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider import org.matrix.android.sdk.api.auth.registration.RegisterThreePid -import org.matrix.android.sdk.internal.network.ssl.Fingerprint +import org.matrix.android.sdk.api.network.ssl.Fingerprint sealed class LoginAction : VectorViewModelAction { data class OnGetStarted(val resetLoginConfig: Boolean) : LoginAction() diff --git a/vector/src/main/java/im/vector/app/features/login/LoginCaptchaFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginCaptchaFragment.kt index fd180c4f97..45b6e5b8cd 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginCaptchaFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginCaptchaFragment.kt @@ -37,7 +37,7 @@ import im.vector.app.R import im.vector.app.core.utils.AssetReader import im.vector.app.databinding.FragmentLoginCaptchaBinding import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.api.util.MatrixJsonParser import timber.log.Timber import java.net.URLDecoder import java.util.Formatter @@ -171,7 +171,7 @@ class LoginCaptchaFragment @Inject constructor( try { // URL decode json = URLDecoder.decode(json, "UTF-8") - javascriptResponse = MoshiProvider.providesMoshi().adapter(JavascriptResponse::class.java).fromJson(json) + javascriptResponse = MatrixJsonParser.getMoshi().adapter(JavascriptResponse::class.java).fromJson(json) } catch (e: Exception) { Timber.e(e, "## shouldOverrideUrlLoading(): failed") } diff --git a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt index bb73ed79b2..b55e393339 100644 --- a/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/LoginWebFragment.kt @@ -38,7 +38,7 @@ import im.vector.app.databinding.FragmentLoginWebBinding import im.vector.app.features.signout.soft.SoftLogoutAction import im.vector.app.features.signout.soft.SoftLogoutViewModel import org.matrix.android.sdk.api.auth.data.Credentials -import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.api.util.MatrixJsonParser import timber.log.Timber import java.net.URLDecoder import javax.inject.Inject @@ -203,7 +203,7 @@ class LoginWebFragment @Inject constructor( try { // URL decode json = URLDecoder.decode(json, "UTF-8") - val adapter = MoshiProvider.providesMoshi().adapter(JavascriptResponse::class.java) + val adapter = MatrixJsonParser.getMoshi().adapter(JavascriptResponse::class.java) javascriptResponse = adapter.fromJson(json) } catch (e: Exception) { Timber.e(e, "## shouldOverrideUrlLoading() : fromJson failed") diff --git a/vector/src/main/java/im/vector/app/features/login/terms/LocalizedFlowDataLoginTermsChecked.kt b/vector/src/main/java/im/vector/app/features/login/terms/LocalizedFlowDataLoginTermsChecked.kt index e6b082ceb7..a248b3471b 100644 --- a/vector/src/main/java/im/vector/app/features/login/terms/LocalizedFlowDataLoginTermsChecked.kt +++ b/vector/src/main/java/im/vector/app/features/login/terms/LocalizedFlowDataLoginTermsChecked.kt @@ -16,7 +16,7 @@ package im.vector.app.features.login.terms -import org.matrix.android.sdk.internal.auth.registration.LocalizedFlowDataLoginTerms +import org.matrix.android.sdk.api.auth.data.LocalizedFlowDataLoginTerms data class LocalizedFlowDataLoginTermsChecked(val localizedFlowDataLoginTerms: LocalizedFlowDataLoginTerms, var checked: Boolean = false) diff --git a/vector/src/main/java/im/vector/app/features/login/terms/LoginTermsFragment.kt b/vector/src/main/java/im/vector/app/features/login/terms/LoginTermsFragment.kt index 43b148dcab..262b79226e 100755 --- a/vector/src/main/java/im/vector/app/features/login/terms/LoginTermsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/login/terms/LoginTermsFragment.kt @@ -31,7 +31,7 @@ import im.vector.app.features.login.AbstractLoginFragment import im.vector.app.features.login.LoginAction import im.vector.app.features.login.LoginViewState import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.internal.auth.registration.LocalizedFlowDataLoginTerms +import org.matrix.android.sdk.api.auth.data.LocalizedFlowDataLoginTerms import javax.inject.Inject @Parcelize diff --git a/vector/src/main/java/im/vector/app/features/login/terms/LoginTermsViewState.kt b/vector/src/main/java/im/vector/app/features/login/terms/LoginTermsViewState.kt index 3641b443e3..3a1dd19a09 100644 --- a/vector/src/main/java/im/vector/app/features/login/terms/LoginTermsViewState.kt +++ b/vector/src/main/java/im/vector/app/features/login/terms/LoginTermsViewState.kt @@ -17,7 +17,7 @@ package im.vector.app.features.login.terms import com.airbnb.mvrx.MavericksState -import org.matrix.android.sdk.internal.auth.registration.LocalizedFlowDataLoginTerms +import org.matrix.android.sdk.api.auth.data.LocalizedFlowDataLoginTerms data class LoginTermsViewState( val localizedFlowDataLoginTermsChecked: List<LocalizedFlowDataLoginTermsChecked> diff --git a/vector/src/main/java/im/vector/app/features/login/terms/PolicyController.kt b/vector/src/main/java/im/vector/app/features/login/terms/PolicyController.kt index 9f0086fb3a..42c39efdac 100644 --- a/vector/src/main/java/im/vector/app/features/login/terms/PolicyController.kt +++ b/vector/src/main/java/im/vector/app/features/login/terms/PolicyController.kt @@ -17,13 +17,14 @@ package im.vector.app.features.login.terms import com.airbnb.epoxy.TypedEpoxyController -import org.matrix.android.sdk.internal.auth.registration.LocalizedFlowDataLoginTerms +import org.matrix.android.sdk.api.auth.data.LocalizedFlowDataLoginTerms import javax.inject.Inject class PolicyController @Inject constructor() : TypedEpoxyController<List<LocalizedFlowDataLoginTermsChecked>>() { var listener: PolicyControllerListener? = null + var horizontalPadding: Int? = null var homeServer: String? = null override fun buildModels(data: List<LocalizedFlowDataLoginTermsChecked>) { @@ -32,6 +33,7 @@ class PolicyController @Inject constructor() : TypedEpoxyController<List<Localiz policyItem { id(entry.localizedFlowDataLoginTerms.policyName) checked(entry.checked) + horizontalPadding(host.horizontalPadding) title(entry.localizedFlowDataLoginTerms.localizedName) subtitle(host.homeServer) clickListener { host.listener?.openPolicy(entry.localizedFlowDataLoginTerms) } diff --git a/vector/src/main/java/im/vector/app/features/login/terms/PolicyItem.kt b/vector/src/main/java/im/vector/app/features/login/terms/PolicyItem.kt index 5c179469d3..ff35f912cf 100644 --- a/vector/src/main/java/im/vector/app/features/login/terms/PolicyItem.kt +++ b/vector/src/main/java/im/vector/app/features/login/terms/PolicyItem.kt @@ -26,6 +26,7 @@ import im.vector.app.R import im.vector.app.core.epoxy.ClickListener import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.onClick +import im.vector.app.core.extensions.setHorizontalPadding @EpoxyModelClass(layout = R.layout.item_policy) abstract class PolicyItem : EpoxyModelWithHolder<PolicyItem.Holder>() { @@ -38,6 +39,9 @@ abstract class PolicyItem : EpoxyModelWithHolder<PolicyItem.Holder>() { @EpoxyAttribute var subtitle: String? = null + @EpoxyAttribute + var horizontalPadding: Int? = null + @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) var checkChangeListener: CompoundButton.OnCheckedChangeListener? = null @@ -46,13 +50,12 @@ abstract class PolicyItem : EpoxyModelWithHolder<PolicyItem.Holder>() { override fun bind(holder: Holder) { super.bind(holder) - holder.let { - it.checkbox.isChecked = checked - it.checkbox.setOnCheckedChangeListener(checkChangeListener) - it.title.text = title - it.subtitle.text = subtitle - it.view.onClick(clickListener) - } + horizontalPadding?.let { holder.view.setHorizontalPadding(it) } + holder.checkbox.isChecked = checked + holder.checkbox.setOnCheckedChangeListener(checkChangeListener) + holder.title.text = title + holder.subtitle.text = subtitle + holder.view.onClick(clickListener) } // Ensure checkbox behaves as expected (remove the listener) diff --git a/vector/src/main/java/im/vector/app/features/login/terms/converter.kt b/vector/src/main/java/im/vector/app/features/login/terms/converter.kt index f054a679bc..64e4fb65d9 100644 --- a/vector/src/main/java/im/vector/app/features/login/terms/converter.kt +++ b/vector/src/main/java/im/vector/app/features/login/terms/converter.kt @@ -16,8 +16,8 @@ package im.vector.app.features.login.terms +import org.matrix.android.sdk.api.auth.data.LocalizedFlowDataLoginTerms import org.matrix.android.sdk.api.auth.registration.TermPolicies -import org.matrix.android.sdk.internal.auth.registration.LocalizedFlowDataLoginTerms /** * This method extract the policies from the login terms parameter, regarding the user language. @@ -48,15 +48,17 @@ fun TermPolicies.toLocalizedLoginTerms(userLanguage: String, val policies = get("policies") if (policies is Map<*, *>) { policies.keys.forEach { policyName -> - val localizedFlowDataLoginTerms = LocalizedFlowDataLoginTerms() - localizedFlowDataLoginTerms.policyName = policyName as String + val localizedFlowDataLoginTermsPolicyName = policyName as String + var localizedFlowDataLoginTermsVersion: String? = null + var localizedFlowDataLoginTermsLocalizedUrl: String? = null + var localizedFlowDataLoginTermsLocalizedName: String? = null val policy = policies[policyName] // Enter this policy if (policy is Map<*, *>) { // Version - localizedFlowDataLoginTerms.version = policy["version"] as String? + localizedFlowDataLoginTermsVersion = policy["version"] as String? var userLanguageUrlAndName: UrlAndName? = null var defaultLanguageUrlAndName: UrlAndName? = null @@ -86,21 +88,26 @@ fun TermPolicies.toLocalizedLoginTerms(userLanguage: String, // Copy found language data by priority when { userLanguageUrlAndName != null -> { - localizedFlowDataLoginTerms.localizedUrl = userLanguageUrlAndName!!.url - localizedFlowDataLoginTerms.localizedName = userLanguageUrlAndName!!.name + localizedFlowDataLoginTermsLocalizedUrl = userLanguageUrlAndName!!.url + localizedFlowDataLoginTermsLocalizedName = userLanguageUrlAndName!!.name } defaultLanguageUrlAndName != null -> { - localizedFlowDataLoginTerms.localizedUrl = defaultLanguageUrlAndName!!.url - localizedFlowDataLoginTerms.localizedName = defaultLanguageUrlAndName!!.name + localizedFlowDataLoginTermsLocalizedUrl = defaultLanguageUrlAndName!!.url + localizedFlowDataLoginTermsLocalizedName = defaultLanguageUrlAndName!!.name } firstUrlAndName != null -> { - localizedFlowDataLoginTerms.localizedUrl = firstUrlAndName!!.url - localizedFlowDataLoginTerms.localizedName = firstUrlAndName!!.name + localizedFlowDataLoginTermsLocalizedUrl = firstUrlAndName!!.url + localizedFlowDataLoginTermsLocalizedName = firstUrlAndName!!.name } } } - result.add(localizedFlowDataLoginTerms) + result.add(LocalizedFlowDataLoginTerms( + policyName = localizedFlowDataLoginTermsPolicyName, + version = localizedFlowDataLoginTermsVersion, + localizedUrl = localizedFlowDataLoginTermsLocalizedUrl, + localizedName = localizedFlowDataLoginTermsLocalizedName + )) } } diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginAction2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginAction2.kt index 62179fbc32..85e2e0cea3 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginAction2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginAction2.kt @@ -21,7 +21,7 @@ import im.vector.app.features.login.LoginConfig import org.matrix.android.sdk.api.auth.data.Credentials import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider import org.matrix.android.sdk.api.auth.registration.RegisterThreePid -import org.matrix.android.sdk.internal.network.ssl.Fingerprint +import org.matrix.android.sdk.api.network.ssl.Fingerprint sealed class LoginAction2 : VectorViewModelAction { // First action diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginCaptchaFragment2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginCaptchaFragment2.kt index 222949bcbd..f729584f51 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginCaptchaFragment2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginCaptchaFragment2.kt @@ -37,7 +37,7 @@ import im.vector.app.core.utils.AssetReader import im.vector.app.databinding.FragmentLoginCaptchaBinding import im.vector.app.features.login.JavascriptResponse import im.vector.app.features.login.LoginCaptchaFragmentArgument -import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.api.util.MatrixJsonParser import timber.log.Timber import java.net.URLDecoder import java.util.Formatter @@ -166,7 +166,7 @@ class LoginCaptchaFragment2 @Inject constructor( try { // URL decode json = URLDecoder.decode(json, "UTF-8") - javascriptResponse = MoshiProvider.providesMoshi().adapter(JavascriptResponse::class.java).fromJson(json) + javascriptResponse = MatrixJsonParser.getMoshi().adapter(JavascriptResponse::class.java).fromJson(json) } catch (e: Exception) { Timber.e(e, "## shouldOverrideUrlLoading(): failed") } diff --git a/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt b/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt index 4427f08309..789cd459ac 100644 --- a/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/LoginWebFragment2.kt @@ -39,7 +39,7 @@ import im.vector.app.features.login.JavascriptResponse import im.vector.app.features.signout.soft.SoftLogoutAction import im.vector.app.features.signout.soft.SoftLogoutViewModel import org.matrix.android.sdk.api.auth.data.Credentials -import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.api.util.MatrixJsonParser import timber.log.Timber import java.net.URLDecoder import javax.inject.Inject @@ -204,7 +204,7 @@ class LoginWebFragment2 @Inject constructor( try { // URL decode json = URLDecoder.decode(json, "UTF-8") - val adapter = MoshiProvider.providesMoshi().adapter(JavascriptResponse::class.java) + val adapter = MatrixJsonParser.getMoshi().adapter(JavascriptResponse::class.java) javascriptResponse = adapter.fromJson(json) } catch (e: Exception) { Timber.e(e, "## shouldOverrideUrlLoading() : fromJson failed") diff --git a/vector/src/main/java/im/vector/app/features/login2/terms/LoginTermsFragment2.kt b/vector/src/main/java/im/vector/app/features/login2/terms/LoginTermsFragment2.kt index 0be696e1c8..303fc5ef17 100755 --- a/vector/src/main/java/im/vector/app/features/login2/terms/LoginTermsFragment2.kt +++ b/vector/src/main/java/im/vector/app/features/login2/terms/LoginTermsFragment2.kt @@ -33,7 +33,7 @@ import im.vector.app.features.login.terms.PolicyController import im.vector.app.features.login2.AbstractLoginFragment2 import im.vector.app.features.login2.LoginAction2 import im.vector.app.features.login2.LoginViewState2 -import org.matrix.android.sdk.internal.auth.registration.LocalizedFlowDataLoginTerms +import org.matrix.android.sdk.api.auth.data.LocalizedFlowDataLoginTerms import javax.inject.Inject /** diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToAction.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToAction.kt index f38049640d..25db811600 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToAction.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToAction.kt @@ -24,7 +24,7 @@ sealed class MatrixToAction : VectorViewModelAction { object FailedToResolveUser : MatrixToAction() object FailedToStartChatting : MatrixToAction() data class JoinSpace(val spaceID: String, val viaServers: List<String>?) : MatrixToAction() - data class JoinRoom(val roomId: String, val viaServers: List<String>?) : MatrixToAction() + data class JoinRoom(val roomIdOrAlias: String, val viaServers: List<String>?) : MatrixToAction() data class OpenSpace(val spaceID: String) : MatrixToAction() data class OpenRoom(val roomId: String) : MatrixToAction() } diff --git a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt index 04c2c8dd44..6d0e380bc9 100644 --- a/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/matrixto/MatrixToBottomSheetViewModel.kt @@ -33,6 +33,7 @@ import im.vector.app.core.resources.StringProvider import im.vector.app.features.createdirect.DirectRoomHelper import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.MatrixPatterns import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.permalinks.PermalinkData @@ -296,8 +297,12 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor( } viewModelScope.launch { try { - session.joinRoom(action.roomId, null, action.viaServers?.take(3) ?: emptyList()) - _viewEvents.post(MatrixToViewEvents.NavigateToRoom(action.roomId)) + session.joinRoom( + roomIdOrAlias = action.roomIdOrAlias, + reason = null, + viaServers = action.viaServers?.take(3) ?: emptyList() + ) + _viewEvents.post(MatrixToViewEvents.NavigateToRoom(getRoomIdFromRoomIdOrAlias(action.roomIdOrAlias))) } catch (failure: Throwable) { _viewEvents.post(MatrixToViewEvents.ShowModalError(errorFormatter.toHumanReadable(failure))) } finally { @@ -309,6 +314,12 @@ class MatrixToBottomSheetViewModel @AssistedInject constructor( } } + private suspend fun getRoomIdFromRoomIdOrAlias(roomIdOrAlias: String): String { + return if (MatrixPatterns.isRoomAlias(roomIdOrAlias)) { + session.getRoomIdByAlias(roomIdOrAlias, true).get().roomId + } else roomIdOrAlias + } + private fun handleStartChatting(action: MatrixToAction.StartChattingWithUser) { setState { copy(startChattingState = Loading()) diff --git a/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt b/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt index 336ba4fa30..fafbc9ba51 100644 --- a/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/media/ImageContentRenderer.kt @@ -46,8 +46,8 @@ import im.vector.app.core.utils.DimensionConverter import kotlinx.parcelize.Parcelize import org.matrix.android.sdk.api.extensions.tryOrNull import org.matrix.android.sdk.api.session.content.ContentUrlResolver +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt import org.matrix.android.sdk.api.session.media.PreviewUrlData -import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt import timber.log.Timber import java.io.File import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/media/RoomEventsAttachmentProvider.kt b/vector/src/main/java/im/vector/app/features/media/RoomEventsAttachmentProvider.kt index 781a176550..cd868c9f2f 100644 --- a/vector/src/main/java/im/vector/app/features/media/RoomEventsAttachmentProvider.kt +++ b/vector/src/main/java/im/vector/app/features/media/RoomEventsAttachmentProvider.kt @@ -21,6 +21,7 @@ import im.vector.app.core.resources.StringProvider import im.vector.lib.attachmentviewer.AttachmentInfo import kotlinx.coroutines.CoroutineScope import org.matrix.android.sdk.api.extensions.tryOrNull +import org.matrix.android.sdk.api.session.crypto.attachments.toElementToDecrypt import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.file.FileService import org.matrix.android.sdk.api.session.room.model.message.MessageContent @@ -32,7 +33,6 @@ import org.matrix.android.sdk.api.session.room.model.message.getFileUrl import org.matrix.android.sdk.api.session.room.model.message.getThumbnailUrl import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.util.MimeTypes -import org.matrix.android.sdk.internal.crypto.attachments.toElementToDecrypt import java.io.File class RoomEventsAttachmentProvider( diff --git a/vector/src/main/java/im/vector/app/features/media/VideoContentRenderer.kt b/vector/src/main/java/im/vector/app/features/media/VideoContentRenderer.kt index 635de2ba16..4e6d19686b 100644 --- a/vector/src/main/java/im/vector/app/features/media/VideoContentRenderer.kt +++ b/vector/src/main/java/im/vector/app/features/media/VideoContentRenderer.kt @@ -31,7 +31,7 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.internal.crypto.attachments.ElementToDecrypt +import org.matrix.android.sdk.api.session.crypto.attachments.ElementToDecrypt import timber.log.Timber import java.net.URLEncoder import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt index bc9d73eb9d..4abc4a79dc 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/DefaultNavigator.kt @@ -178,6 +178,9 @@ class DefaultNavigator @Inject constructor( Navigator.PostSwitchSpaceAction.OpenAddExistingRooms -> { startActivity(context, SpaceManageActivity.newIntent(context, spaceId, ManageType.AddRooms), false) } + Navigator.PostSwitchSpaceAction.OpenRoomList -> { + startActivity(context, SpaceExploreActivity.newIntent(context, spaceId), buildTask = false) + } is Navigator.PostSwitchSpaceAction.OpenDefaultRoom -> { val args = TimelineArgs( postSwitchSpaceAction.roomId, diff --git a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt index 452c97eb69..7d355e4518 100644 --- a/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt +++ b/vector/src/main/java/im/vector/app/features/navigation/Navigator.kt @@ -54,8 +54,9 @@ interface Navigator { sealed class PostSwitchSpaceAction { object None : PostSwitchSpaceAction() - data class OpenDefaultRoom(val roomId: String, val showShareSheet: Boolean) : PostSwitchSpaceAction() object OpenAddExistingRooms : PostSwitchSpaceAction() + object OpenRoomList : PostSwitchSpaceAction() + data class OpenDefaultRoom(val roomId: String, val showShareSheet: Boolean) : PostSwitchSpaceAction() } fun switchToSpace(context: Context, spaceId: String, postSwitchSpaceAction: PostSwitchSpaceAction) diff --git a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt index 3c9b985df5..855774e512 100644 --- a/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt +++ b/vector/src/main/java/im/vector/app/features/notifications/NotifiableEventResolver.kt @@ -27,6 +27,7 @@ import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.content.ContentUrlResolver import org.matrix.android.sdk.api.session.crypto.MXCryptoError +import org.matrix.android.sdk.api.session.crypto.model.OlmDecryptionResult import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.isEdition @@ -41,7 +42,6 @@ import org.matrix.android.sdk.api.session.room.timeline.TimelineEvent import org.matrix.android.sdk.api.session.room.timeline.getEditedEventId import org.matrix.android.sdk.api.session.room.timeline.getLastMessageContent import org.matrix.android.sdk.api.util.toMatrixItem -import org.matrix.android.sdk.internal.crypto.algorithms.olm.OlmDecryptionResult import timber.log.Timber import java.util.UUID import javax.inject.Inject @@ -155,7 +155,8 @@ class NotifiableEventResolver @Inject constructor( // only convert encrypted messages to NotifiableMessageEvents when (event.root.getClearType()) { EventType.MESSAGE, - in EventType.POLL_START -> { + in EventType.POLL_START, + in EventType.STATE_ROOM_BEACON_INFO -> { val body = displayableEventFormatter.format(event, isDm = room.roomSummary()?.isDirect.orFalse(), appendAuthor = false).toString() val roomName = room.roomSummary()?.displayName ?: "" val senderDisplayName = event.senderInfo.disambiguatedDisplayName @@ -187,7 +188,7 @@ class NotifiableEventResolver @Inject constructor( soundName = null ) } - else -> null + else -> null } } } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/DirectLoginUseCase.kt b/vector/src/main/java/im/vector/app/features/onboarding/DirectLoginUseCase.kt index 7ef4dfb609..171d8f7bb5 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/DirectLoginUseCase.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/DirectLoginUseCase.kt @@ -17,6 +17,7 @@ package im.vector.app.features.onboarding import im.vector.app.R +import im.vector.app.core.extensions.andThen import im.vector.app.core.resources.StringProvider import im.vector.app.features.onboarding.OnboardingAction.LoginOrRegister import org.matrix.android.sdk.api.MatrixPatterns.getDomain @@ -24,7 +25,6 @@ import org.matrix.android.sdk.api.auth.AuthenticationService import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.api.auth.wellknown.WellknownResult import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.internal.extensions.andThen import javax.inject.Inject class DirectLoginUseCase @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt index 7510f23584..9f7dce56ea 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingAction.kt @@ -22,14 +22,21 @@ import im.vector.app.features.login.LoginConfig import im.vector.app.features.login.ServerType import im.vector.app.features.login.SignMode import org.matrix.android.sdk.api.auth.data.Credentials -import org.matrix.android.sdk.internal.network.ssl.Fingerprint +import org.matrix.android.sdk.api.network.ssl.Fingerprint sealed interface OnboardingAction : VectorViewModelAction { data class OnGetStarted(val resetLoginConfig: Boolean, val onboardingFlow: OnboardingFlow) : OnboardingAction data class OnIAlreadyHaveAnAccount(val resetLoginConfig: Boolean, val onboardingFlow: OnboardingFlow) : OnboardingAction data class UpdateServerType(val serverType: ServerType) : OnboardingAction - data class UpdateHomeServer(val homeServerUrl: String) : OnboardingAction + + sealed interface HomeServerChange : OnboardingAction { + val homeServerUrl: String + + data class SelectHomeServer(override val homeServerUrl: String) : HomeServerChange + data class EditHomeServer(override val homeServerUrl: String) : HomeServerChange + } + data class UpdateUseCase(val useCase: FtueUseCase) : OnboardingAction object ResetUseCase : OnboardingAction data class UpdateSignMode(val signMode: SignMode) : OnboardingAction diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt index 853b0c330e..ee406aff48 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewEvents.kt @@ -37,8 +37,10 @@ sealed class OnboardingViewEvents : VectorViewEvents { object OpenUseCaseSelection : OnboardingViewEvents() object OpenServerSelection : OnboardingViewEvents() object OpenCombinedRegister : OnboardingViewEvents() + object EditServerSelection : OnboardingViewEvents() data class OnServerSelectionDone(val serverType: ServerType) : OnboardingViewEvents() object OnLoginFlowRetrieved : OnboardingViewEvents() + object OnHomeserverEdited : OnboardingViewEvents() data class OnSignModeSelected(val signMode: SignMode) : OnboardingViewEvents() object OnForgetPasswordClicked : OnboardingViewEvents() object OnResetPasswordSendThreePidDone : OnboardingViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt index dbd257464e..2b286e6d93 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewModel.kt @@ -41,13 +41,13 @@ import im.vector.app.features.login.LoginMode import im.vector.app.features.login.ReAuthHelper import im.vector.app.features.login.ServerType import im.vector.app.features.login.SignMode +import im.vector.app.features.onboarding.StartAuthenticationFlowUseCase.StartAuthenticationResult import kotlinx.coroutines.Job import kotlinx.coroutines.flow.firstOrNull import kotlinx.coroutines.launch import org.matrix.android.sdk.api.auth.AuthenticationService import org.matrix.android.sdk.api.auth.HomeServerHistoryService import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig -import org.matrix.android.sdk.api.auth.data.LoginFlowTypes import org.matrix.android.sdk.api.auth.login.LoginWizard import org.matrix.android.sdk.api.auth.registration.FlowResult import org.matrix.android.sdk.api.auth.registration.RegistrationResult @@ -75,6 +75,7 @@ class OnboardingViewModel @AssistedInject constructor( private val uriFilenameResolver: UriFilenameResolver, private val registrationActionHandler: RegistrationActionHandler, private val directLoginUseCase: DirectLoginUseCase, + private val startAuthenticationFlowUseCase: StartAuthenticationFlowUseCase, private val vectorOverrides: VectorOverrides ) : VectorViewModel<OnboardingViewState, OnboardingAction, OnboardingViewEvents>(initialState) { @@ -107,6 +108,7 @@ class OnboardingViewModel @AssistedInject constructor( private var currentHomeServerConnectionConfig: HomeServerConnectionConfig? = null private val matrixOrgUrl = stringProvider.getString(R.string.matrix_org_server_url).ensureTrailingSlash() + private val defaultHomeserverUrl = matrixOrgUrl private val registrationWizard: RegistrationWizard get() = authenticationService.getRegistrationWizard() @@ -139,14 +141,14 @@ class OnboardingViewModel @AssistedInject constructor( is OnboardingAction.UpdateServerType -> handleUpdateServerType(action) is OnboardingAction.UpdateSignMode -> handleUpdateSignMode(action) is OnboardingAction.InitWith -> handleInitWith(action) - is OnboardingAction.UpdateHomeServer -> handleUpdateHomeserver(action).also { lastAction = action } + is OnboardingAction.HomeServerChange -> withAction(action) { handleHomeserverChange(action) } is OnboardingAction.LoginOrRegister -> handleLoginOrRegister(action).also { lastAction = action } is OnboardingAction.Register -> handleRegisterWith(action).also { lastAction = action } is OnboardingAction.LoginWithToken -> handleLoginWithToken(action) is OnboardingAction.WebLoginSuccess -> handleWebLoginSuccess(action) is OnboardingAction.ResetPassword -> handleResetPassword(action) is OnboardingAction.ResetPasswordMailConfirmed -> handleResetPasswordMailConfirmed() - is OnboardingAction.PostRegisterAction -> handleRegisterAction(action.registerAction) + is OnboardingAction.PostRegisterAction -> handleRegisterAction(action.registerAction, ::emitFlowResultViewEvent) is OnboardingAction.ResetAction -> handleResetAction(action) is OnboardingAction.UserAcceptCertificate -> handleUserAcceptCertificate(action) OnboardingAction.ClearHomeServerHistory -> handleClearHomeServerHistory() @@ -161,25 +163,30 @@ class OnboardingViewModel @AssistedInject constructor( } } + private fun withAction(action: OnboardingAction, block: (OnboardingAction) -> Unit) { + lastAction = action + block(action) + } + private fun handleSplashAction(resetConfig: Boolean, onboardingFlow: OnboardingFlow) { if (resetConfig) { loginConfig = null } setState { copy(onboardingFlow = onboardingFlow) } - val configUrl = loginConfig?.homeServerUrl?.takeIf { it.isNotEmpty() } - if (configUrl != null) { - // Use config from uri - val homeServerConnectionConfig = homeServerConnectionConfigFactory.create(configUrl) - if (homeServerConnectionConfig == null) { - // Url is invalid, in this case, just use the regular flow - Timber.w("Url from config url was invalid: $configUrl") - continueToPageAfterSplash(onboardingFlow) - } else { - getLoginFlow(homeServerConnectionConfig, ServerType.Other) + return when (val config = loginConfig.toHomeserverConfig()) { + null -> continueToPageAfterSplash(onboardingFlow) + else -> startAuthenticationFlow(trigger = null, config, ServerType.Other) + } + } + + private fun LoginConfig?.toHomeserverConfig(): HomeServerConnectionConfig? { + return this?.homeServerUrl?.takeIf { it.isNotEmpty() }?.let { url -> + homeServerConnectionConfigFactory.create(url).also { + if (it == null) { + Timber.w("Url from config url was invalid: $url") + } } - } else { - continueToPageAfterSplash(onboardingFlow) } } @@ -200,12 +207,12 @@ class OnboardingViewModel @AssistedInject constructor( // It happens when we get the login flow, or during direct authentication. // So alter the homeserver config and retrieve again the login flow when (val finalLastAction = lastAction) { - is OnboardingAction.UpdateHomeServer -> { + is OnboardingAction.HomeServerChange.SelectHomeServer -> { currentHomeServerConnectionConfig ?.let { it.copy(allowedFingerprints = it.allowedFingerprints + action.fingerprint) } - ?.let { getLoginFlow(it) } + ?.let { startAuthenticationFlow(finalLastAction, it) } } - is OnboardingAction.LoginOrRegister -> + is OnboardingAction.LoginOrRegister -> handleDirectLogin( finalLastAction, HomeServerConnectionConfig.Builder() @@ -214,7 +221,7 @@ class OnboardingViewModel @AssistedInject constructor( .withAllowedFingerPrints(listOf(action.fingerprint)) .build() ) - else -> Unit + else -> Unit } } @@ -249,41 +256,52 @@ class OnboardingViewModel @AssistedInject constructor( } } - private fun handleRegisterAction(action: RegisterAction) { + private fun handleRegisterAction(action: RegisterAction, onNextRegistrationStepAction: (FlowResult) -> Unit) { currentJob = viewModelScope.launch { if (action.hasLoadingState()) { setState { copy(isLoading = true) } } - runCatching { registrationActionHandler.handleRegisterAction(registrationWizard, action) } - .fold( - onSuccess = { - when { - action.ignoresResult() -> { - // do nothing - } - else -> when (it) { - is RegistrationResult.Success -> onSessionCreated(it.session, isAccountCreated = true) - is RegistrationResult.FlowResponse -> onFlowResponse(it.flowResult) - } - } - }, - onFailure = { - if (it !is CancellationException) { - _viewEvents.post(OnboardingViewEvents.Failure(it)) - } - } - ) + internalRegisterAction(action, onNextRegistrationStepAction) setState { copy(isLoading = false) } } } + private suspend fun internalRegisterAction(action: RegisterAction, onNextRegistrationStepAction: (FlowResult) -> Unit) { + runCatching { registrationActionHandler.handleRegisterAction(registrationWizard, action) } + .fold( + onSuccess = { + when { + action.ignoresResult() -> { + // do nothing + } + else -> when (it) { + is RegistrationResult.Success -> onSessionCreated(it.session, isAccountCreated = true) + is RegistrationResult.FlowResponse -> onFlowResponse(it.flowResult, onNextRegistrationStepAction) + } + } + }, + onFailure = { + if (it !is CancellationException) { + _viewEvents.post(OnboardingViewEvents.Failure(it)) + } + } + ) + } + + private fun emitFlowResultViewEvent(flowResult: FlowResult) { + _viewEvents.post(OnboardingViewEvents.RegistrationFlowResult(flowResult, isRegistrationStarted)) + } + private fun handleRegisterWith(action: OnboardingAction.Register) { reAuthHelper.data = action.password - handleRegisterAction(RegisterAction.CreateAccount( - action.username, - action.password, - action.initialDeviceName - )) + handleRegisterAction( + RegisterAction.CreateAccount( + action.username, + action.password, + action.initialDeviceName + ), + ::emitFlowResultViewEvent + ) } private fun handleResetAction(action: OnboardingAction.ResetAction) { @@ -291,24 +309,16 @@ class OnboardingViewModel @AssistedInject constructor( currentJob = null when (action) { - OnboardingAction.ResetHomeServerType -> { - setState { - copy( - serverType = ServerType.Unknown - ) - } + OnboardingAction.ResetHomeServerType -> { + setState { copy(serverType = ServerType.Unknown) } } - OnboardingAction.ResetHomeServerUrl -> { + OnboardingAction.ResetHomeServerUrl -> { viewModelScope.launch { authenticationService.reset() setState { copy( isLoading = false, - homeServerUrlFromUser = null, - homeServerUrl = null, - loginMode = LoginMode.Unknown, - serverType = ServerType.Unknown, - loginModeSupportedTypes = emptyList() + selectedHomeserver = SelectedHomeserverState(), ) } } @@ -318,8 +328,6 @@ class OnboardingViewModel @AssistedInject constructor( copy( isLoading = false, signMode = SignMode.Unknown, - loginMode = LoginMode.Unknown, - loginModeSupportedTypes = emptyList() ) } } @@ -341,27 +349,23 @@ class OnboardingViewModel @AssistedInject constructor( } private fun handleUpdateSignMode(action: OnboardingAction.UpdateSignMode) { - setState { - copy( - signMode = action.signMode - ) - } - + updateSignMode(action.signMode) when (action.signMode) { - SignMode.SignUp -> handleRegisterAction(RegisterAction.StartRegistration) + SignMode.SignUp -> handleRegisterAction(RegisterAction.StartRegistration, ::emitFlowResultViewEvent) SignMode.SignIn -> startAuthenticationFlow() SignMode.SignInWithMatrixId -> _viewEvents.post(OnboardingViewEvents.OnSignModeSelected(SignMode.SignInWithMatrixId)) SignMode.Unknown -> Unit } } + private fun updateSignMode(signMode: SignMode) { + setState { copy(signMode = signMode) } + } + private fun handleUpdateUseCase(action: OnboardingAction.UpdateUseCase) { setState { copy(useCase = action.useCase) } when (vectorFeatures.isOnboardingCombinedRegisterEnabled()) { - true -> { - handle(OnboardingAction.UpdateHomeServer(matrixOrgUrl)) - OnboardingViewEvents.OpenCombinedRegister - } + true -> handle(OnboardingAction.HomeServerChange.SelectHomeServer(defaultHomeserverUrl)) false -> _viewEvents.post(OnboardingViewEvents.OpenServerSelection) } } @@ -381,7 +385,7 @@ class OnboardingViewModel @AssistedInject constructor( ServerType.Unknown -> Unit /* Should not happen */ ServerType.MatrixOrg -> // Request login flow here - handle(OnboardingAction.UpdateHomeServer(matrixOrgUrl)) + handle(OnboardingAction.HomeServerChange.SelectHomeServer(matrixOrgUrl)) ServerType.EMS, ServerType.Other -> _viewEvents.post(OnboardingViewEvents.OnServerSelectionDone(action.serverType)) } @@ -516,18 +520,17 @@ class OnboardingViewModel @AssistedInject constructor( _viewEvents.post(OnboardingViewEvents.OnSignModeSelected(SignMode.SignIn)) } - private fun onFlowResponse(flowResult: FlowResult) { + private suspend fun onFlowResponse(flowResult: FlowResult, onNextRegistrationStepAction: (FlowResult) -> Unit) { // If dummy stage is mandatory, and password is already sent, do the dummy stage now if (isRegistrationStarted && flowResult.missingStages.any { it is Stage.Dummy && it.mandatory }) { - handleRegisterDummy() + handleRegisterDummy(onNextRegistrationStepAction) } else { - // Notify the user - _viewEvents.post(OnboardingViewEvents.RegistrationFlowResult(flowResult, isRegistrationStarted)) + onNextRegistrationStepAction(flowResult) } } - private fun handleRegisterDummy() { - handleRegisterAction(RegisterAction.RegisterDummy) + private suspend fun handleRegisterDummy(onNextRegistrationStepAction: (FlowResult) -> Unit) { + internalRegisterAction(RegisterAction.RegisterDummy, onNextRegistrationStepAction) } private suspend fun onSessionCreated(session: Session, isAccountCreated: Boolean) { @@ -571,7 +574,7 @@ class OnboardingViewModel @AssistedInject constructor( } private fun handleWebLoginSuccess(action: OnboardingAction.WebLoginSuccess) = withState { state -> - val homeServerConnectionConfigFinal = homeServerConnectionConfigFactory.create(state.homeServerUrl) + val homeServerConnectionConfigFinal = homeServerConnectionConfigFactory.create(state.selectedHomeserver.upstreamUrl) if (homeServerConnectionConfigFinal == null) { // Should not happen @@ -588,85 +591,66 @@ class OnboardingViewModel @AssistedInject constructor( } } - private fun handleUpdateHomeserver(action: OnboardingAction.UpdateHomeServer) { + private fun handleHomeserverChange(action: OnboardingAction.HomeServerChange) { val homeServerConnectionConfig = homeServerConnectionConfigFactory.create(action.homeServerUrl) if (homeServerConnectionConfig == null) { // This is invalid _viewEvents.post(OnboardingViewEvents.Failure(Throwable("Unable to create a HomeServerConnectionConfig"))) } else { - getLoginFlow(homeServerConnectionConfig) + startAuthenticationFlow(action, homeServerConnectionConfig) } } - private fun getLoginFlow(homeServerConnectionConfig: HomeServerConnectionConfig, - serverTypeOverride: ServerType? = null) { + private fun startAuthenticationFlow( + trigger: OnboardingAction?, + homeServerConnectionConfig: HomeServerConnectionConfig, + serverTypeOverride: ServerType? = null + ) { currentHomeServerConnectionConfig = homeServerConnectionConfig currentJob = viewModelScope.launch { - authenticationService.cancelPendingLoginOrRegistration() + setState { copy(isLoading = true) } + runCatching { startAuthenticationFlowUseCase.execute(homeServerConnectionConfig) }.fold( + onSuccess = { onAuthenticationStartedSuccess(trigger, homeServerConnectionConfig, it, serverTypeOverride) }, + onFailure = { _viewEvents.post(OnboardingViewEvents.Failure(it)) } + ) + setState { copy(isLoading = false) } + } + } - setState { - copy( - isLoading = true, - // If user has entered https://matrix.org, ensure that server type is ServerType.MatrixOrg - // It is also useful to set the value again in the case of a certificate error on matrix.org - serverType = if (homeServerConnectionConfig.homeServerUri.toString() == matrixOrgUrl) { - ServerType.MatrixOrg - } else { - serverTypeOverride ?: serverType - } - ) - } + private suspend fun onAuthenticationStartedSuccess( + trigger: OnboardingAction?, + config: HomeServerConnectionConfig, + authResult: StartAuthenticationResult, + serverTypeOverride: ServerType? + ) { + rememberHomeServer(config.homeServerUri.toString()) + if (authResult.isHomeserverOutdated) { + _viewEvents.post(OnboardingViewEvents.OutdatedHomeserver) + } - val data = try { - authenticationService.getLoginFlow(homeServerConnectionConfig) - } catch (failure: Throwable) { - setState { - copy( - isLoading = false, - // If we were trying to retrieve matrix.org login flow, also reset the serverType - serverType = if (serverType == ServerType.MatrixOrg) ServerType.Unknown else serverType - ) + when (trigger) { + is OnboardingAction.HomeServerChange.EditHomeServer -> { + when (awaitState().onboardingFlow) { + OnboardingFlow.SignUp -> internalRegisterAction(RegisterAction.StartRegistration) { _ -> + updateServerSelection(config, serverTypeOverride, authResult) + _viewEvents.post(OnboardingViewEvents.OnHomeserverEdited) + } + else -> throw IllegalArgumentException("developer error") } - _viewEvents.post(OnboardingViewEvents.Failure(failure)) - null } - - data ?: return@launch - - // Valid Homeserver, add it to the history. - // Note: we add what the user has input, data.homeServerUrlBase can be different - rememberHomeServer(homeServerConnectionConfig.homeServerUri.toString()) - - val loginMode = when { - // SSO login is taken first - data.supportedLoginTypes.contains(LoginFlowTypes.SSO) && - data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.SsoAndPassword(data.ssoIdentityProviders) - data.supportedLoginTypes.contains(LoginFlowTypes.SSO) -> LoginMode.Sso(data.ssoIdentityProviders) - data.supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.Password - else -> LoginMode.Unsupported - } - - setState { - copy( - isLoading = false, - homeServerUrlFromUser = homeServerConnectionConfig.homeServerUri.toString(), - homeServerUrl = data.homeServerUrl, - loginMode = loginMode, - loginModeSupportedTypes = data.supportedLoginTypes.toList() - ) - } - if ((loginMode == LoginMode.Password && !data.isLoginAndRegistrationSupported) || - data.isOutdatedHomeserver) { - // Notify the UI - _viewEvents.post(OnboardingViewEvents.OutdatedHomeserver) - } - - withState { - if (loginMode.supportsSignModeScreen()) { - when (it.onboardingFlow) { - OnboardingFlow.SignIn -> handleUpdateSignMode(OnboardingAction.UpdateSignMode(SignMode.SignIn)) - OnboardingFlow.SignUp -> handleUpdateSignMode(OnboardingAction.UpdateSignMode(SignMode.SignUp)) + is OnboardingAction.HomeServerChange.SelectHomeServer -> { + updateServerSelection(config, serverTypeOverride, authResult) + if (authResult.selectedHomeserver.preferredLoginMode.supportsSignModeScreen()) { + when (awaitState().onboardingFlow) { + OnboardingFlow.SignIn -> { + updateSignMode(SignMode.SignIn) + internalRegisterAction(RegisterAction.StartRegistration, ::emitFlowResultViewEvent) + } + OnboardingFlow.SignUp -> { + updateSignMode(SignMode.SignUp) + internalRegisterAction(RegisterAction.StartRegistration, ::emitFlowResultViewEvent) + } OnboardingFlow.SignInSignUp, null -> { _viewEvents.post(OnboardingViewEvents.OnLoginFlowRetrieved) @@ -676,6 +660,31 @@ class OnboardingViewModel @AssistedInject constructor( _viewEvents.post(OnboardingViewEvents.OnLoginFlowRetrieved) } } + else -> { + updateServerSelection(config, serverTypeOverride, authResult) + _viewEvents.post(OnboardingViewEvents.OnLoginFlowRetrieved) + } + } + } + + private fun updateServerSelection(config: HomeServerConnectionConfig, serverTypeOverride: ServerType?, authResult: StartAuthenticationResult) { + setState { + copy( + serverType = alignServerTypeAfterSubmission(config, serverTypeOverride), + selectedHomeserver = authResult.selectedHomeserver, + ) + } + } + + /** + * If user has entered https://matrix.org, ensure that server type is ServerType.MatrixOrg + * It is also useful to set the value again in the case of a certificate error on matrix.org + **/ + private fun OnboardingViewState.alignServerTypeAfterSubmission(config: HomeServerConnectionConfig, serverTypeOverride: ServerType?): ServerType { + return if (config.homeServerUri.toString() == matrixOrgUrl) { + ServerType.MatrixOrg + } else { + serverTypeOverride ?: serverType } } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt index b98e811679..442a0a7df1 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/OnboardingViewState.kt @@ -40,26 +40,17 @@ data class OnboardingViewState( val signMode: SignMode = SignMode.Unknown, @PersistState val resetPasswordEmail: String? = null, - @PersistState - val homeServerUrlFromUser: String? = null, - - // Can be modified after a Wellknown request - @PersistState - val homeServerUrl: String? = null, // For SSO session recovery @PersistState val deviceId: String? = null, - // Network result - @PersistState - val loginMode: LoginMode = LoginMode.Unknown, - // Supported types for the login. We cannot use a sealed class for LoginType because it is not serializable - @PersistState - val loginModeSupportedTypes: List<String> = emptyList(), val knownCustomHomeServersUrls: List<String> = emptyList(), val isForceLoginFallbackEnabled: Boolean = false, + @PersistState + val selectedHomeserver: SelectedHomeserverState = SelectedHomeserverState(), + @PersistState val personalizationState: PersonalizationState = PersonalizationState() ) : MavericksState @@ -70,6 +61,15 @@ enum class OnboardingFlow { SignInSignUp } +@Parcelize +data class SelectedHomeserverState( + val description: String? = null, + val userFacingUrl: String? = null, + val upstreamUrl: String? = null, + val preferredLoginMode: LoginMode = LoginMode.Unknown, + val supportedLoginTypes: List<String> = emptyList(), +) : Parcelable + @Parcelize data class PersonalizationState( val supportsChangingDisplayName: Boolean = false, diff --git a/vector/src/main/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCase.kt b/vector/src/main/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCase.kt new file mode 100644 index 0000000000..53e1c47fa1 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCase.kt @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.onboarding + +import im.vector.app.R +import im.vector.app.core.extensions.containsAllItems +import im.vector.app.core.resources.StringProvider +import im.vector.app.core.utils.ensureTrailingSlash +import im.vector.app.features.login.LoginMode +import org.matrix.android.sdk.api.auth.AuthenticationService +import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig +import org.matrix.android.sdk.api.auth.data.LoginFlowResult +import org.matrix.android.sdk.api.auth.data.LoginFlowTypes +import javax.inject.Inject + +class StartAuthenticationFlowUseCase @Inject constructor( + private val authenticationService: AuthenticationService, + private val stringProvider: StringProvider +) { + + suspend fun execute(config: HomeServerConnectionConfig): StartAuthenticationResult { + authenticationService.cancelPendingLoginOrRegistration() + val authFlow = authenticationService.getLoginFlow(config) + val preferredLoginMode = authFlow.findPreferredLoginMode() + val selection = createSelectedHomeserver(authFlow, config, preferredLoginMode) + val isOutdated = (preferredLoginMode == LoginMode.Password && !authFlow.isLoginAndRegistrationSupported) || authFlow.isOutdatedHomeserver + return StartAuthenticationResult(isOutdated, selection) + } + + private fun createSelectedHomeserver( + authFlow: LoginFlowResult, + config: HomeServerConnectionConfig, + preferredLoginMode: LoginMode + ) = SelectedHomeserverState( + description = when (config.homeServerUri.toString()) { + matrixOrgUrl() -> stringProvider.getString(R.string.ftue_auth_create_account_matrix_dot_org_server_description) + else -> null + }, + userFacingUrl = config.homeServerUri.toString(), + upstreamUrl = authFlow.homeServerUrl, + preferredLoginMode = preferredLoginMode, + supportedLoginTypes = authFlow.supportedLoginTypes + ) + + private fun matrixOrgUrl() = stringProvider.getString(R.string.matrix_org_server_url).ensureTrailingSlash() + + private fun LoginFlowResult.findPreferredLoginMode() = when { + supportedLoginTypes.containsAllItems(LoginFlowTypes.SSO, LoginFlowTypes.PASSWORD) -> LoginMode.SsoAndPassword(ssoIdentityProviders) + supportedLoginTypes.contains(LoginFlowTypes.SSO) -> LoginMode.Sso(ssoIdentityProviders) + supportedLoginTypes.contains(LoginFlowTypes.PASSWORD) -> LoginMode.Password + else -> LoginMode.Unsupported + } + + data class StartAuthenticationResult( + val isHomeserverOutdated: Boolean, + val selectedHomeserver: SelectedHomeserverState + ) +} diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/AbstractSSOFtueAuthFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/AbstractSSOFtueAuthFragment.kt index 2e9925516c..a032181e4d 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/AbstractSSOFtueAuthFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/AbstractSSOFtueAuthFragment.kt @@ -37,7 +37,7 @@ abstract class AbstractSSOFtueAuthFragment<VB : ViewBinding> : AbstractFtueAuthF override fun onStart() { super.onStart() - val hasSSO = withState(viewModel) { it.loginMode.hasSso() } + val hasSSO = withState(viewModel) { it.selectedHomeserver.preferredLoginMode.hasSso() } if (hasSSO) { val packageName = CustomTabsClient.getPackageName(requireContext(), null) @@ -67,7 +67,7 @@ abstract class AbstractSSOFtueAuthFragment<VB : ViewBinding> : AbstractFtueAuthF override fun onStop() { super.onStop() - val hasSSO = withState(viewModel) { it.loginMode.hasSso() } + val hasSSO = withState(viewModel) { it.selectedHomeserver.preferredLoginMode.hasSso() } if (hasSSO) { customTabsServiceConnection?.let { requireContext().unbindService(it) } customTabsServiceConnection = null @@ -88,7 +88,7 @@ abstract class AbstractSSOFtueAuthFragment<VB : ViewBinding> : AbstractFtueAuthF private fun prefetchIfNeeded() { withState(viewModel) { state -> - if (state.loginMode.hasSso() && state.loginMode.ssoIdentityProviders().isNullOrEmpty()) { + if (state.selectedHomeserver.preferredLoginMode.hasSso() && state.selectedHomeserver.preferredLoginMode.ssoIdentityProviders().isNullOrEmpty()) { // in this case we can prefetch (not other cases for privacy concerns) viewModel.getSsoUrl( redirectUrl = SSORedirectRouterActivity.VECTOR_REDIRECT_URL, diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/CaptchaWebview.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/CaptchaWebview.kt new file mode 100644 index 0000000000..558c26fe56 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/CaptchaWebview.kt @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.onboarding.ftueauth + +import android.annotation.SuppressLint +import android.content.DialogInterface +import android.graphics.Bitmap +import android.net.http.SslError +import android.os.Build +import android.view.KeyEvent +import android.view.View +import android.webkit.SslErrorHandler +import android.webkit.WebResourceRequest +import android.webkit.WebResourceResponse +import android.webkit.WebView +import android.webkit.WebViewClient +import androidx.core.view.isVisible +import androidx.fragment.app.Fragment +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import im.vector.app.R +import im.vector.app.core.utils.AssetReader +import im.vector.app.features.login.JavascriptResponse +import im.vector.app.features.onboarding.OnboardingViewState +import org.matrix.android.sdk.api.util.MatrixJsonParser +import timber.log.Timber +import java.net.URLDecoder +import java.util.Formatter +import javax.inject.Inject + +class CaptchaWebview @Inject constructor( + private val assetReader: AssetReader +) { + + @SuppressLint("SetJavaScriptEnabled") + fun setupWebView( + container: Fragment, + webView: WebView, + progressView: View, + siteKey: String, + state: OnboardingViewState, + onSuccess: (String) -> Unit + ) { + webView.settings.javaScriptEnabled = true + + val reCaptchaPage = assetReader.readAssetFile("reCaptchaPage.html") ?: error("missing asset reCaptchaPage.html") + + val html = Formatter().format(reCaptchaPage, siteKey).toString() + val mime = "text/html" + val encoding = "utf-8" + + val homeServerUrl = state.selectedHomeserver.upstreamUrl ?: error("missing url of homeserver") + webView.loadDataWithBaseURL(homeServerUrl, html, mime, encoding, null) + webView.requestLayout() + + webView.webViewClient = object : WebViewClient() { + override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { + super.onPageStarted(view, url, favicon) + if (container.isAdded) { + progressView.isVisible = true + } + } + + override fun onPageFinished(view: WebView, url: String) { + super.onPageFinished(view, url) + if (container.isAdded) { + progressView.isVisible = false + } + } + + override fun onReceivedSslError(view: WebView, handler: SslErrorHandler, error: SslError) { + Timber.d("## onReceivedSslError() : ${error.certificate}") + if (container.isAdded) { + showSslErrorDialog(container, handler) + } + } + + private fun onError(errorMessage: String) { + Timber.e("## onError() : $errorMessage") + } + + @SuppressLint("NewApi") + override fun onReceivedHttpError(view: WebView, request: WebResourceRequest, errorResponse: WebResourceResponse) { + super.onReceivedHttpError(view, request, errorResponse) + when { + request.url.toString().endsWith("favicon.ico") -> { + // ignore favicon errors + } + else -> onError(errorResponse.toText()) + } + } + + override fun onReceivedError(view: WebView, errorCode: Int, description: String, failingUrl: String) { + @Suppress("DEPRECATION") + super.onReceivedError(view, errorCode, description, failingUrl) + onError(description) + } + + override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { + if (url?.startsWith("js:") == true) { + val javascriptResponse = parseJsonFromUrl(url) + val response = javascriptResponse?.response + if (javascriptResponse?.action == "verifyCallback" && response != null) { + onSuccess(response) + } + } + return true + } + + private fun parseJsonFromUrl(url: String): JavascriptResponse? { + return try { + val json = URLDecoder.decode(url.substringAfter("js:"), "UTF-8") + MatrixJsonParser.getMoshi().adapter(JavascriptResponse::class.java).fromJson(json) + } catch (e: Exception) { + Timber.e(e, "## shouldOverrideUrlLoading(): failed") + null + } + } + } + } + + private fun showSslErrorDialog(container: Fragment, handler: SslErrorHandler) { + MaterialAlertDialogBuilder(container.requireActivity()) + .setMessage(R.string.ssl_could_not_verify) + .setPositiveButton(R.string.ssl_trust) { _, _ -> + Timber.d("## onReceivedSslError() : the user trusted") + handler.proceed() + } + .setNegativeButton(R.string.ssl_do_not_trust) { _, _ -> + Timber.d("## onReceivedSslError() : the user did not trust") + handler.cancel() + } + .setOnKeyListener(DialogInterface.OnKeyListener { dialog, keyCode, event -> + if (event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) { + handler.cancel() + Timber.d("## onReceivedSslError() : the user dismisses the trust dialog.") + dialog.dismiss() + return@OnKeyListener true + } + false + }) + .setCancelable(false) + .show() + } +} + +private fun WebResourceResponse.toText() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) reasonPhrase else toString() diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCaptchaFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCaptchaFragment.kt index c9c693ef3b..a3665a8f40 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCaptchaFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCaptchaFragment.kt @@ -1,5 +1,5 @@ /* - * Copyright 2022 New Vector Ltd + * Copyright (c) 2022 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,35 +16,15 @@ package im.vector.app.features.onboarding.ftueauth -import android.annotation.SuppressLint -import android.content.DialogInterface -import android.graphics.Bitmap -import android.net.http.SslError -import android.os.Build import android.os.Parcelable -import android.view.KeyEvent import android.view.LayoutInflater import android.view.ViewGroup -import android.webkit.SslErrorHandler -import android.webkit.WebResourceRequest -import android.webkit.WebResourceResponse -import android.webkit.WebView -import android.webkit.WebViewClient -import androidx.core.view.isVisible import com.airbnb.mvrx.args -import com.google.android.material.dialog.MaterialAlertDialogBuilder -import im.vector.app.R -import im.vector.app.core.utils.AssetReader -import im.vector.app.databinding.FragmentLoginCaptchaBinding -import im.vector.app.features.login.JavascriptResponse +import im.vector.app.databinding.FragmentFtueLoginCaptchaBinding import im.vector.app.features.onboarding.OnboardingAction import im.vector.app.features.onboarding.OnboardingViewState import im.vector.app.features.onboarding.RegisterAction import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.internal.di.MoshiProvider -import timber.log.Timber -import java.net.URLDecoder -import java.util.Formatter import javax.inject.Inject @Parcelize @@ -53,141 +33,17 @@ data class FtueAuthCaptchaFragmentArgument( ) : Parcelable /** - * In this screen, the user is asked to confirm he is not a robot + * In this screen, the user is asked to confirm they are not a robot */ class FtueAuthCaptchaFragment @Inject constructor( - private val assetReader: AssetReader -) : AbstractFtueAuthFragment<FragmentLoginCaptchaBinding>() { - - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginCaptchaBinding { - return FragmentLoginCaptchaBinding.inflate(inflater, container, false) - } + private val captchaWebview: CaptchaWebview +) : AbstractFtueAuthFragment<FragmentFtueLoginCaptchaBinding>() { private val params: FtueAuthCaptchaFragmentArgument by args() - private var isWebViewLoaded = false - @SuppressLint("SetJavaScriptEnabled") - private fun setupWebView(state: OnboardingViewState) { - views.loginCaptchaWevView.settings.javaScriptEnabled = true - - val reCaptchaPage = assetReader.readAssetFile("reCaptchaPage.html") ?: error("missing asset reCaptchaPage.html") - - val html = Formatter().format(reCaptchaPage, params.siteKey).toString() - val mime = "text/html" - val encoding = "utf-8" - - val homeServerUrl = state.homeServerUrl ?: error("missing url of homeserver") - views.loginCaptchaWevView.loadDataWithBaseURL(homeServerUrl, html, mime, encoding, null) - views.loginCaptchaWevView.requestLayout() - - views.loginCaptchaWevView.webViewClient = object : WebViewClient() { - override fun onPageStarted(view: WebView?, url: String?, favicon: Bitmap?) { - super.onPageStarted(view, url, favicon) - - if (!isAdded) { - return - } - - // Show loader - views.loginCaptchaProgress.isVisible = true - } - - override fun onPageFinished(view: WebView, url: String) { - super.onPageFinished(view, url) - - if (!isAdded) { - return - } - - // Hide loader - views.loginCaptchaProgress.isVisible = false - } - - override fun onReceivedSslError(view: WebView, handler: SslErrorHandler, error: SslError) { - Timber.d("## onReceivedSslError() : ${error.certificate}") - - if (!isAdded) { - return - } - - MaterialAlertDialogBuilder(requireActivity()) - .setMessage(R.string.ssl_could_not_verify) - .setPositiveButton(R.string.ssl_trust) { _, _ -> - Timber.d("## onReceivedSslError() : the user trusted") - handler.proceed() - } - .setNegativeButton(R.string.ssl_do_not_trust) { _, _ -> - Timber.d("## onReceivedSslError() : the user did not trust") - handler.cancel() - } - .setOnKeyListener(DialogInterface.OnKeyListener { dialog, keyCode, event -> - if (event.action == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) { - handler.cancel() - Timber.d("## onReceivedSslError() : the user dismisses the trust dialog.") - dialog.dismiss() - return@OnKeyListener true - } - false - }) - .setCancelable(false) - .show() - } - - // common error message - private fun onError(errorMessage: String) { - Timber.e("## onError() : $errorMessage") - - // TODO - // Toast.makeText(this@AccountCreationCaptchaActivity, errorMessage, Toast.LENGTH_LONG).show() - - // on error case, close this activity - // runOnUiThread(Runnable { finish() }) - } - - @SuppressLint("NewApi") - override fun onReceivedHttpError(view: WebView, request: WebResourceRequest, errorResponse: WebResourceResponse) { - super.onReceivedHttpError(view, request, errorResponse) - - if (request.url.toString().endsWith("favicon.ico")) { - // Ignore this error - return - } - - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - onError(errorResponse.reasonPhrase) - } else { - onError(errorResponse.toString()) - } - } - - override fun onReceivedError(view: WebView, errorCode: Int, description: String, failingUrl: String) { - @Suppress("DEPRECATION") - super.onReceivedError(view, errorCode, description, failingUrl) - onError(description) - } - - override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean { - if (url?.startsWith("js:") == true) { - var json = url.substring(3) - var javascriptResponse: JavascriptResponse? = null - - try { - // URL decode - json = URLDecoder.decode(json, "UTF-8") - javascriptResponse = MoshiProvider.providesMoshi().adapter(JavascriptResponse::class.java).fromJson(json) - } catch (e: Exception) { - Timber.e(e, "## shouldOverrideUrlLoading(): failed") - } - - val response = javascriptResponse?.response - if (javascriptResponse?.action == "verifyCallback" && response != null) { - viewModel.handle(OnboardingAction.PostRegisterAction(RegisterAction.CaptchaDone(response))) - } - } - return true - } - } + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueLoginCaptchaBinding { + return FragmentFtueLoginCaptchaBinding.inflate(inflater, container, false) } override fun resetViewModel() { @@ -196,7 +52,9 @@ class FtueAuthCaptchaFragment @Inject constructor( override fun updateWithState(state: OnboardingViewState) { if (!isWebViewLoaded) { - setupWebView(state) + captchaWebview.setupWebView(this, views.loginCaptchaWevView, views.loginCaptchaProgress, params.siteKey, state) { + viewModel.handle(OnboardingAction.PostRegisterAction(RegisterAction.CaptchaDone(it))) + } isWebViewLoaded = true } } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedRegisterFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedRegisterFragment.kt index 3a7d51d14b..0755f18c8c 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedRegisterFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedRegisterFragment.kt @@ -36,12 +36,13 @@ import im.vector.app.core.extensions.hasSurroundingSpaces import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.hidePassword import im.vector.app.core.extensions.realignPercentagesToParent -import im.vector.app.databinding.FragmentFtueSignUpCombinedBinding +import im.vector.app.core.extensions.toReducedUrl +import im.vector.app.databinding.FragmentFtueCombinedRegisterBinding import im.vector.app.features.login.LoginMode import im.vector.app.features.login.SSORedirectRouterActivity -import im.vector.app.features.login.ServerType import im.vector.app.features.login.SocialLoginButtonsView import im.vector.app.features.onboarding.OnboardingAction +import im.vector.app.features.onboarding.OnboardingViewEvents import im.vector.app.features.onboarding.OnboardingViewState import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.launchIn @@ -55,17 +56,19 @@ import org.matrix.android.sdk.api.failure.isUsernameInUse import org.matrix.android.sdk.api.failure.isWeakPassword import javax.inject.Inject -class FtueAuthCombinedRegisterFragment @Inject constructor() : AbstractSSOFtueAuthFragment<FragmentFtueSignUpCombinedBinding>() { +class FtueAuthCombinedRegisterFragment @Inject constructor() : AbstractSSOFtueAuthFragment<FragmentFtueCombinedRegisterBinding>() { - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueSignUpCombinedBinding { - return FragmentFtueSignUpCombinedBinding.inflate(inflater, container, false) + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueCombinedRegisterBinding { + return FragmentFtueCombinedRegisterBinding.inflate(inflater, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) setupSubmitButton() - views.createAccountRoot.realignPercentagesToParent() + views.editServerButton.debouncedClicks { + viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.EditServerSelection)) + } views.createAccountPasswordInput.editText().setOnEditorActionListener { _, actionId, _ -> if (actionId == EditorInfo.IME_ACTION_DONE) { @@ -164,6 +167,9 @@ class FtueAuthCombinedRegisterFragment @Inject constructor() : AbstractSSOFtueAu setupUi(state) setupAutoFill() + views.selectedServerName.text = state.selectedHomeserver.userFacingUrl.toReducedUrl() + views.selectedServerDescription.text = state.selectedHomeserver.description + if (state.isLoading) { // Ensure password is hidden views.createAccountPasswordInput.editText().hidePassword() @@ -171,8 +177,8 @@ class FtueAuthCombinedRegisterFragment @Inject constructor() : AbstractSSOFtueAu } private fun setupUi(state: OnboardingViewState) { - when (state.loginMode) { - is LoginMode.SsoAndPassword -> renderSsoProviders(state.deviceId, state.loginMode.ssoIdentityProviders) + when (state.selectedHomeserver.preferredLoginMode) { + is LoginMode.SsoAndPassword -> renderSsoProviders(state.deviceId, state.selectedHomeserver.preferredLoginMode.ssoIdentityProviders) else -> hideSsoProviders() } } @@ -201,6 +207,6 @@ class FtueAuthCombinedRegisterFragment @Inject constructor() : AbstractSSOFtueAu views.createAccountPasswordInput.setAutofillHints(HintConstants.AUTOFILL_HINT_NEW_PASSWORD) } } -} -private fun OnboardingViewState.isNumericOnlyUserIdForbidden() = serverType == ServerType.MatrixOrg + private fun OnboardingViewState.isNumericOnlyUserIdForbidden() = selectedHomeserver.userFacingUrl == getString(R.string.matrix_org_server_url) +} diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedServerSelectionFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedServerSelectionFragment.kt new file mode 100644 index 0000000000..2e6057288a --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthCombinedServerSelectionFragment.kt @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.onboarding.ftueauth + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.inputmethod.EditorInfo +import androidx.lifecycle.lifecycleScope +import im.vector.app.R +import im.vector.app.core.extensions.content +import im.vector.app.core.extensions.editText +import im.vector.app.core.extensions.realignPercentagesToParent +import im.vector.app.core.extensions.toReducedUrl +import im.vector.app.core.utils.ensureProtocol +import im.vector.app.core.utils.ensureTrailingSlash +import im.vector.app.core.utils.openUrlInExternalBrowser +import im.vector.app.databinding.FragmentFtueServerSelectionCombinedBinding +import im.vector.app.features.onboarding.OnboardingAction +import im.vector.app.features.onboarding.OnboardingViewEvents +import im.vector.app.features.onboarding.OnboardingViewState +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import org.matrix.android.sdk.api.failure.isHomeserverUnavailable +import reactivecircus.flowbinding.android.widget.textChanges +import javax.inject.Inject + +class FtueAuthCombinedServerSelectionFragment @Inject constructor() : AbstractFtueAuthFragment<FragmentFtueServerSelectionCombinedBinding>() { + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueServerSelectionCombinedBinding { + return FragmentFtueServerSelectionCombinedBinding.inflate(inflater, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupViews() + } + + private fun setupViews() { + views.chooseServerRoot.realignPercentagesToParent() + views.chooseServerToolbar.setNavigationOnClickListener { + viewModel.handle(OnboardingAction.PostViewEvent(OnboardingViewEvents.OnBack)) + } + views.chooseServerInput.editText?.setOnEditorActionListener { _, actionId, _ -> + when (actionId) { + EditorInfo.IME_ACTION_DONE -> { + updateServerUrl() + } + } + false + } + views.chooseServerGetInTouch.debouncedClicks { openUrlInExternalBrowser(requireContext(), getString(R.string.ftue_ems_url)) } + views.chooseServerSubmit.debouncedClicks { updateServerUrl() } + views.chooseServerInput.editText().textChanges() + .onEach { views.chooseServerInput.error = null } + .launchIn(lifecycleScope) + } + + private fun updateServerUrl() { + viewModel.handle(OnboardingAction.HomeServerChange.EditHomeServer(views.chooseServerInput.content().ensureProtocol().ensureTrailingSlash())) + } + + override fun resetViewModel() { + // do nothing + } + + override fun updateWithState(state: OnboardingViewState) { + if (views.chooseServerInput.content().isEmpty()) { + val userUrlInput = state.selectedHomeserver.userFacingUrl?.toReducedUrlKeepingSchemaIfInsecure() + views.chooseServerInput.editText().setText(userUrlInput) + } + } + + override fun onError(throwable: Throwable) { + views.chooseServerInput.error = when { + throwable.isHomeserverUnavailable() -> getString(R.string.login_error_homeserver_not_found) + else -> errorFormatter.toHumanReadable(throwable) + } + } + + private fun String.toReducedUrlKeepingSchemaIfInsecure() = toReducedUrl(keepSchema = this.startsWith("http://")) +} diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLegacyStyleCaptchaFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLegacyStyleCaptchaFragment.kt new file mode 100644 index 0000000000..2accab00e0 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLegacyStyleCaptchaFragment.kt @@ -0,0 +1,61 @@ +/* + * Copyright 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.onboarding.ftueauth + +import android.os.Parcelable +import android.view.LayoutInflater +import android.view.ViewGroup +import com.airbnb.mvrx.args +import im.vector.app.databinding.FragmentLoginCaptchaBinding +import im.vector.app.features.onboarding.OnboardingAction +import im.vector.app.features.onboarding.OnboardingViewState +import im.vector.app.features.onboarding.RegisterAction +import kotlinx.parcelize.Parcelize +import javax.inject.Inject + +@Parcelize +data class FtueAuthLegacyStyleCaptchaFragmentArgument( + val siteKey: String +) : Parcelable + +/** + * In this screen, the user is asked to confirm they are not a robot + */ +class FtueAuthLegacyStyleCaptchaFragment @Inject constructor( + private val captchaWebview: CaptchaWebview +) : AbstractFtueAuthFragment<FragmentLoginCaptchaBinding>() { + + private val params: FtueAuthLegacyStyleCaptchaFragmentArgument by args() + private var isWebViewLoaded = false + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginCaptchaBinding { + return FragmentLoginCaptchaBinding.inflate(inflater, container, false) + } + + override fun resetViewModel() { + viewModel.handle(OnboardingAction.ResetAuthenticationAttempt) + } + + override fun updateWithState(state: OnboardingViewState) { + if (!isWebViewLoaded) { + captchaWebview.setupWebView(this, views.loginCaptchaWevView, views.loginCaptchaProgress, params.siteKey, state) { + viewModel.handle(OnboardingAction.PostRegisterAction(RegisterAction.CaptchaDone(it))) + } + isWebViewLoaded = true + } + } +} diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLoginFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLoginFragment.kt index e561f85f25..4888b43946 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLoginFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthLoginFragment.kt @@ -184,7 +184,7 @@ class FtueAuthLoginFragment @Inject constructor() : AbstractSSOFtueAuthFragment< ServerType.MatrixOrg -> { views.loginServerIcon.isVisible = true views.loginServerIcon.setImageResource(R.drawable.ic_logo_matrix_org) - views.loginTitle.text = getString(resId, state.homeServerUrlFromUser.toReducedUrl()) + views.loginTitle.text = getString(resId, state.selectedHomeserver.userFacingUrl.toReducedUrl()) views.loginNotice.text = getString(R.string.login_server_matrix_org_text) } ServerType.EMS -> { @@ -195,16 +195,16 @@ class FtueAuthLoginFragment @Inject constructor() : AbstractSSOFtueAuthFragment< } ServerType.Other -> { views.loginServerIcon.isVisible = false - views.loginTitle.text = getString(resId, state.homeServerUrlFromUser.toReducedUrl()) + views.loginTitle.text = getString(resId, state.selectedHomeserver.userFacingUrl.toReducedUrl()) views.loginNotice.text = getString(R.string.login_server_other_text) } ServerType.Unknown -> Unit /* Should not happen */ } views.loginPasswordNotice.isVisible = false - if (state.loginMode is LoginMode.SsoAndPassword) { + if (state.selectedHomeserver.preferredLoginMode is LoginMode.SsoAndPassword) { views.loginSocialLoginContainer.isVisible = true - views.loginSocialLoginButtons.ssoIdentityProviders = state.loginMode.ssoIdentityProviders?.sorted() + views.loginSocialLoginButtons.ssoIdentityProviders = state.selectedHomeserver.preferredLoginMode.ssoIdentityProviders?.sorted() views.loginSocialLoginButtons.listener = object : SocialLoginButtonsView.InteractionListener { override fun onProviderSelected(id: String?) { viewModel.getSsoUrl( diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordFragment.kt index b612ec34b5..4ec02f677a 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthResetPasswordFragment.kt @@ -59,7 +59,7 @@ class FtueAuthResetPasswordFragment @Inject constructor() : AbstractFtueAuthFrag } private fun setupUi(state: OnboardingViewState) { - views.resetPasswordTitle.text = getString(R.string.login_reset_password_on, state.homeServerUrlFromUser.toReducedUrl()) + views.resetPasswordTitle.text = getString(R.string.login_reset_password_on, state.selectedHomeserver.userFacingUrl.toReducedUrl()) } private fun setupSubmitButton() { diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthServerUrlFormFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthServerUrlFormFragment.kt index 2cae9743a7..df304d028d 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthServerUrlFormFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthServerUrlFormFragment.kt @@ -139,7 +139,7 @@ class FtueAuthServerUrlFormFragment @Inject constructor() : AbstractFtueAuthFrag } else -> { views.loginServerUrlFormHomeServerUrl.setText(serverUrl, false /* to avoid completion dialog flicker*/) - viewModel.handle(OnboardingAction.UpdateHomeServer(serverUrl)) + viewModel.handle(OnboardingAction.HomeServerChange.SelectHomeServer(serverUrl)) } } } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSignUpSignInSelectionFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSignUpSignInSelectionFragment.kt index e9ae5022e2..dda5e0c36a 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSignUpSignInSelectionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthSignUpSignInSelectionFragment.kt @@ -20,6 +20,7 @@ import android.os.Bundle import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.annotation.DrawableRes import androidx.core.view.isVisible import com.airbnb.mvrx.withState import im.vector.app.R @@ -55,32 +56,30 @@ class FtueAuthSignUpSignInSelectionFragment @Inject constructor() : AbstractSSOF views.loginSignupSigninSignIn.setOnClickListener { signIn() } } - private fun setupUi(state: OnboardingViewState) { + private fun render(state: OnboardingViewState) { when (state.serverType) { - ServerType.MatrixOrg -> { - views.loginSignupSigninServerIcon.setImageResource(R.drawable.ic_logo_matrix_org) - views.loginSignupSigninServerIcon.isVisible = true - views.loginSignupSigninTitle.text = getString(R.string.login_connect_to, state.homeServerUrlFromUser.toReducedUrl()) - views.loginSignupSigninText.text = getString(R.string.login_server_matrix_org_text) - } - ServerType.EMS -> { - views.loginSignupSigninServerIcon.setImageResource(R.drawable.ic_logo_element_matrix_services) - views.loginSignupSigninServerIcon.isVisible = true - views.loginSignupSigninTitle.text = getString(R.string.login_connect_to_modular) - views.loginSignupSigninText.text = state.homeServerUrlFromUser.toReducedUrl() - } - ServerType.Other -> { - views.loginSignupSigninServerIcon.isVisible = false - views.loginSignupSigninTitle.text = getString(R.string.login_server_other_title) - views.loginSignupSigninText.text = getString(R.string.login_connect_to, state.homeServerUrlFromUser.toReducedUrl()) - } + ServerType.MatrixOrg -> renderServerInformation( + icon = R.drawable.ic_logo_matrix_org, + title = getString(R.string.login_connect_to, state.selectedHomeserver.userFacingUrl.toReducedUrl()), + subtitle = getString(R.string.login_server_matrix_org_text) + ) + ServerType.EMS -> renderServerInformation( + icon = R.drawable.ic_logo_element_matrix_services, + title = getString(R.string.login_connect_to_modular), + subtitle = state.selectedHomeserver.userFacingUrl.toReducedUrl() + ) + ServerType.Other -> renderServerInformation( + icon = null, + title = getString(R.string.login_server_other_title), + subtitle = getString(R.string.login_connect_to, state.selectedHomeserver.userFacingUrl.toReducedUrl()) + ) ServerType.Unknown -> Unit /* Should not happen */ } - when (state.loginMode) { + when (state.selectedHomeserver.preferredLoginMode) { is LoginMode.SsoAndPassword -> { views.loginSignupSigninSignInSocialLoginContainer.isVisible = true - views.loginSignupSigninSocialLoginButtons.ssoIdentityProviders = state.loginMode.ssoIdentityProviders()?.sorted() + views.loginSignupSigninSocialLoginButtons.ssoIdentityProviders = state.selectedHomeserver.preferredLoginMode.ssoIdentityProviders()?.sorted() views.loginSignupSigninSocialLoginButtons.listener = object : SocialLoginButtonsView.InteractionListener { override fun onProviderSelected(id: String?) { viewModel.getSsoUrl( @@ -100,8 +99,16 @@ class FtueAuthSignUpSignInSelectionFragment @Inject constructor() : AbstractSSOF } } + private fun renderServerInformation(@DrawableRes icon: Int?, title: String, subtitle: String) { + icon?.let { views.loginSignupSigninServerIcon.setImageResource(it) } + views.loginSignupSigninServerIcon.isVisible = icon != null + views.loginSignupSigninServerIcon.setImageResource(R.drawable.ic_logo_matrix_org) + views.loginSignupSigninTitle.text = title + views.loginSignupSigninText.text = subtitle + } + private fun setupButtons(state: OnboardingViewState) { - when (state.loginMode) { + when (state.selectedHomeserver.preferredLoginMode) { is LoginMode.Sso -> { // change to only one button that is sign in with sso views.loginSignupSigninSubmit.text = getString(R.string.login_signin_sso) @@ -115,7 +122,7 @@ class FtueAuthSignUpSignInSelectionFragment @Inject constructor() : AbstractSSOF } private fun submit() = withState(viewModel) { state -> - if (state.loginMode is LoginMode.Sso) { + if (state.selectedHomeserver.preferredLoginMode is LoginMode.Sso) { viewModel.getSsoUrl( redirectUrl = SSORedirectRouterActivity.VECTOR_REDIRECT_URL, deviceId = state.deviceId, @@ -136,7 +143,7 @@ class FtueAuthSignUpSignInSelectionFragment @Inject constructor() : AbstractSSOF } override fun updateWithState(state: OnboardingViewState) { - setupUi(state) + render(state) setupButtons(state) } } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt index 4c7bf47233..d5816762df 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthVariant.kt @@ -17,6 +17,7 @@ package im.vector.app.features.onboarding.ftueauth import android.content.Intent +import android.os.Parcelable import android.view.View import android.view.ViewGroup import androidx.core.view.ViewCompat @@ -51,8 +52,9 @@ import im.vector.app.features.onboarding.OnboardingVariant import im.vector.app.features.onboarding.OnboardingViewEvents import im.vector.app.features.onboarding.OnboardingViewModel import im.vector.app.features.onboarding.OnboardingViewState +import im.vector.app.features.onboarding.ftueauth.terms.FtueAuthLegacyStyleTermsFragment import im.vector.app.features.onboarding.ftueauth.terms.FtueAuthTermsFragment -import im.vector.app.features.onboarding.ftueauth.terms.FtueAuthTermsFragmentArgument +import im.vector.app.features.onboarding.ftueauth.terms.FtueAuthTermsLegacyStyleFragmentArgument import org.matrix.android.sdk.api.auth.registration.FlowResult import org.matrix.android.sdk.api.auth.registration.Stage import org.matrix.android.sdk.api.extensions.tryOrNull @@ -201,20 +203,18 @@ class FtueAuthVariant( is OnboardingViewEvents.OnSendEmailSuccess -> { // Pop the enter email Fragment supportFragmentManager.popBackStack(FRAGMENT_REGISTRATION_STAGE_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE) - activity.addFragmentToBackstack(views.loginFragmentContainer, + addRegistrationStageFragmentToBackstack( FtueAuthWaitForEmailFragment::class.java, FtueAuthWaitForEmailFragmentArgument(viewEvents.email), - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption) + ) } is OnboardingViewEvents.OnSendMsisdnSuccess -> { // Pop the enter Msisdn Fragment supportFragmentManager.popBackStack(FRAGMENT_REGISTRATION_STAGE_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE) - activity.addFragmentToBackstack(views.loginFragmentContainer, + addRegistrationStageFragmentToBackstack( FtueAuthGenericTextInputFormFragment::class.java, FtueAuthGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.ConfirmMsisdn, true, viewEvents.msisdn), - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption) + ) } is OnboardingViewEvents.Failure, is OnboardingViewEvents.Loading -> @@ -233,16 +233,19 @@ class FtueAuthVariant( OnboardingViewEvents.OnChooseProfilePicture -> onChooseProfilePicture() OnboardingViewEvents.OnPersonalizationComplete -> onPersonalizationComplete() OnboardingViewEvents.OnBack -> activity.popBackstack() + OnboardingViewEvents.EditServerSelection -> { + activity.addFragmentToBackstack( + views.loginFragmentContainer, + FtueAuthCombinedServerSelectionFragment::class.java, + option = commonOption + ) + } + OnboardingViewEvents.OnHomeserverEdited -> activity.popBackstack() } } private fun openCombinedRegister() { - activity.addFragmentToBackstack( - views.loginFragmentContainer, - FtueAuthCombinedRegisterFragment::class.java, - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption - ) + addRegistrationStageFragmentToBackstack(FtueAuthCombinedRegisterFragment::class.java) } private fun registrationShouldFallback(registrationFlowResult: OnboardingViewEvents.RegistrationFlowResult) = @@ -299,18 +302,18 @@ class FtueAuthVariant( private fun handleSignInSelected(state: OnboardingViewState) { if (isForceLoginFallbackEnabled) { - onLoginModeNotSupported(state.loginModeSupportedTypes) + onLoginModeNotSupported(state.selectedHomeserver.supportedLoginTypes) } else { disambiguateLoginMode(state) } } - private fun disambiguateLoginMode(state: OnboardingViewState) = when (state.loginMode) { + private fun disambiguateLoginMode(state: OnboardingViewState) = when (state.selectedHomeserver.preferredLoginMode) { LoginMode.Unknown, is LoginMode.Sso -> error("Developer error") is LoginMode.SsoAndPassword, LoginMode.Password -> openAuthLoginFragmentWithTag(FRAGMENT_LOGIN_TAG) - LoginMode.Unsupported -> onLoginModeNotSupported(state.loginModeSupportedTypes) + LoginMode.Unsupported -> onLoginModeNotSupported(state.selectedHomeserver.supportedLoginTypes) } private fun openAuthLoginFragmentWithTag(tag: String) { @@ -331,7 +334,7 @@ class FtueAuthVariant( private fun handleSignInWithMatrixId(state: OnboardingViewState) { if (isForceLoginFallbackEnabled) { - onLoginModeNotSupported(state.loginModeSupportedTypes) + onLoginModeNotSupported(state.selectedHomeserver.supportedLoginTypes) } else { openAuthLoginFragmentWithTag(FRAGMENT_LOGIN_TAG) } @@ -374,30 +377,46 @@ class FtueAuthVariant( supportFragmentManager.popBackStack(FRAGMENT_REGISTRATION_STAGE_TAG, FragmentManager.POP_BACK_STACK_INCLUSIVE) when (stage) { - is Stage.ReCaptcha -> activity.addFragmentToBackstack(views.loginFragmentContainer, - FtueAuthCaptchaFragment::class.java, - FtueAuthCaptchaFragmentArgument(stage.publicKey), - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption) - is Stage.Email -> activity.addFragmentToBackstack(views.loginFragmentContainer, + is Stage.ReCaptcha -> onCaptcha(stage) + is Stage.Email -> addRegistrationStageFragmentToBackstack( FtueAuthGenericTextInputFormFragment::class.java, FtueAuthGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.SetEmail, stage.mandatory), - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption) - is Stage.Msisdn -> activity.addFragmentToBackstack(views.loginFragmentContainer, + ) + is Stage.Msisdn -> addRegistrationStageFragmentToBackstack( FtueAuthGenericTextInputFormFragment::class.java, FtueAuthGenericTextInputFormFragmentArgument(TextInputFormFragmentMode.SetMsisdn, stage.mandatory), - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption) - is Stage.Terms -> activity.addFragmentToBackstack(views.loginFragmentContainer, - FtueAuthTermsFragment::class.java, - FtueAuthTermsFragmentArgument(stage.policies.toLocalizedLoginTerms(activity.getString(R.string.resources_language))), - tag = FRAGMENT_REGISTRATION_STAGE_TAG, - option = commonOption) + ) + is Stage.Terms -> onTerms(stage) else -> Unit // Should not happen } } + private fun onTerms(stage: Stage.Terms) { + when { + vectorFeatures.isOnboardingCombinedRegisterEnabled() -> addRegistrationStageFragmentToBackstack( + FtueAuthTermsFragment::class.java, + FtueAuthTermsLegacyStyleFragmentArgument(stage.policies.toLocalizedLoginTerms(activity.getString(R.string.resources_language))), + ) + else -> addRegistrationStageFragmentToBackstack( + FtueAuthLegacyStyleTermsFragment::class.java, + FtueAuthTermsLegacyStyleFragmentArgument(stage.policies.toLocalizedLoginTerms(activity.getString(R.string.resources_language))), + ) + } + } + + private fun onCaptcha(stage: Stage.ReCaptcha) { + when { + vectorFeatures.isOnboardingCombinedRegisterEnabled() -> addRegistrationStageFragmentToBackstack( + FtueAuthCaptchaFragment::class.java, + FtueAuthCaptchaFragmentArgument(stage.publicKey), + ) + else -> addRegistrationStageFragmentToBackstack( + FtueAuthLegacyStyleCaptchaFragment::class.java, + FtueAuthLegacyStyleCaptchaFragmentArgument(stage.publicKey), + ) + } + } + private fun onAccountSignedIn() { navigateToHome(createdAccount = false) } @@ -439,4 +458,14 @@ class FtueAuthVariant( useCustomAnimation = true ) } + + private fun addRegistrationStageFragmentToBackstack(fragmentClass: Class<out Fragment>, params: Parcelable? = null) { + activity.addFragmentToBackstack( + views.loginFragmentContainer, + fragmentClass, + params, + tag = FRAGMENT_REGISTRATION_STAGE_TAG, + option = commonOption + ) + } } diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthWebFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthWebFragment.kt index 69b002c271..26b9a38d83 100644 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthWebFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/FtueAuthWebFragment.kt @@ -40,7 +40,7 @@ import im.vector.app.features.onboarding.OnboardingAction import im.vector.app.features.onboarding.OnboardingViewEvents import im.vector.app.features.onboarding.OnboardingViewState import org.matrix.android.sdk.api.auth.data.Credentials -import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.api.util.MatrixJsonParser import timber.log.Timber import java.net.URLDecoder import javax.inject.Inject @@ -200,7 +200,7 @@ class FtueAuthWebFragment @Inject constructor( try { // URL decode json = URLDecoder.decode(json, "UTF-8") - val adapter = MoshiProvider.providesMoshi().adapter(JavascriptResponse::class.java) + val adapter = MatrixJsonParser.getMoshi().adapter(JavascriptResponse::class.java) javascriptResponse = adapter.fromJson(json) } catch (e: Exception) { Timber.e(e, "## shouldOverrideUrlLoading() : fromJson failed") diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/terms/FtueAuthLegacyStyleTermsFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/terms/FtueAuthLegacyStyleTermsFragment.kt new file mode 100755 index 0000000000..727e3d5cbd --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/terms/FtueAuthLegacyStyleTermsFragment.kt @@ -0,0 +1,124 @@ +/* + * Copyright 2018 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.onboarding.ftueauth.terms + +import android.os.Bundle +import android.os.Parcelable +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.airbnb.mvrx.args +import im.vector.app.core.extensions.cleanup +import im.vector.app.core.extensions.configureWith +import im.vector.app.core.extensions.toReducedUrl +import im.vector.app.core.utils.openUrlInChromeCustomTab +import im.vector.app.databinding.FragmentLoginTermsBinding +import im.vector.app.features.login.terms.LocalizedFlowDataLoginTermsChecked +import im.vector.app.features.login.terms.LoginTermsViewState +import im.vector.app.features.login.terms.PolicyController +import im.vector.app.features.onboarding.OnboardingAction +import im.vector.app.features.onboarding.OnboardingViewState +import im.vector.app.features.onboarding.RegisterAction +import im.vector.app.features.onboarding.ftueauth.AbstractFtueAuthFragment +import kotlinx.parcelize.Parcelize +import org.matrix.android.sdk.api.auth.data.LocalizedFlowDataLoginTerms +import javax.inject.Inject + +@Parcelize +data class FtueAuthTermsLegacyStyleFragmentArgument( + val localizedFlowDataLoginTerms: List<LocalizedFlowDataLoginTerms> +) : Parcelable + +/** + * LoginTermsFragment displays the list of policies the user has to accept + */ +class FtueAuthLegacyStyleTermsFragment @Inject constructor( + private val policyController: PolicyController +) : AbstractFtueAuthFragment<FragmentLoginTermsBinding>(), + PolicyController.PolicyControllerListener { + + private val params: FtueAuthTermsLegacyStyleFragmentArgument by args() + + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginTermsBinding { + return FragmentLoginTermsBinding.inflate(inflater, container, false) + } + + private var loginTermsViewState: LoginTermsViewState = LoginTermsViewState(emptyList()) + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + setupViews() + views.loginTermsPolicyList.configureWith(policyController) + policyController.listener = this + + val list = ArrayList<LocalizedFlowDataLoginTermsChecked>() + + params.localizedFlowDataLoginTerms + .forEach { + list.add(LocalizedFlowDataLoginTermsChecked(it)) + } + + loginTermsViewState = LoginTermsViewState(list) + } + + private fun setupViews() { + views.loginTermsSubmit.setOnClickListener { submit() } + } + + override fun onDestroyView() { + views.loginTermsPolicyList.cleanup() + policyController.listener = null + super.onDestroyView() + } + + private fun renderState() { + policyController.setData(loginTermsViewState.localizedFlowDataLoginTermsChecked) + views.loginTermsSubmit.isEnabled = loginTermsViewState.allChecked() + } + + override fun setChecked(localizedFlowDataLoginTerms: LocalizedFlowDataLoginTerms, isChecked: Boolean) { + if (isChecked) { + loginTermsViewState.check(localizedFlowDataLoginTerms) + } else { + loginTermsViewState.uncheck(localizedFlowDataLoginTerms) + } + + renderState() + } + + override fun openPolicy(localizedFlowDataLoginTerms: LocalizedFlowDataLoginTerms) { + localizedFlowDataLoginTerms.localizedUrl + ?.takeIf { it.isNotBlank() } + ?.let { + openUrlInChromeCustomTab(requireContext(), null, it) + } + } + + private fun submit() { + viewModel.handle(OnboardingAction.PostRegisterAction(RegisterAction.AcceptTerms)) + } + + override fun updateWithState(state: OnboardingViewState) { + policyController.homeServer = state.selectedHomeserver.userFacingUrl.toReducedUrl() + renderState() + } + + override fun resetViewModel() { + viewModel.handle(OnboardingAction.ResetAuthenticationAttempt) + } +} diff --git a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/terms/FtueAuthTermsFragment.kt b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/terms/FtueAuthTermsFragment.kt old mode 100755 new mode 100644 index f6a7769cbd..4a25e35537 --- a/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/terms/FtueAuthTermsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/onboarding/ftueauth/terms/FtueAuthTermsFragment.kt @@ -1,5 +1,5 @@ /* - * Copyright 2018 New Vector Ltd + * Copyright (c) 2022 New Vector Ltd * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,16 +17,18 @@ package im.vector.app.features.onboarding.ftueauth.terms import android.os.Bundle -import android.os.Parcelable import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import androidx.constraintlayout.widget.ConstraintLayout +import androidx.core.view.doOnLayout import com.airbnb.mvrx.args +import im.vector.app.R import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.extensions.toReducedUrl import im.vector.app.core.utils.openUrlInChromeCustomTab -import im.vector.app.databinding.FragmentLoginTermsBinding +import im.vector.app.databinding.FragmentFtueLoginTermsBinding import im.vector.app.features.login.terms.LocalizedFlowDataLoginTermsChecked import im.vector.app.features.login.terms.LoginTermsViewState import im.vector.app.features.login.terms.PolicyController @@ -34,50 +36,46 @@ import im.vector.app.features.onboarding.OnboardingAction import im.vector.app.features.onboarding.OnboardingViewState import im.vector.app.features.onboarding.RegisterAction import im.vector.app.features.onboarding.ftueauth.AbstractFtueAuthFragment -import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.internal.auth.registration.LocalizedFlowDataLoginTerms +import org.matrix.android.sdk.api.auth.data.LocalizedFlowDataLoginTerms import javax.inject.Inject - -@Parcelize -data class FtueAuthTermsFragmentArgument( - val localizedFlowDataLoginTerms: List<LocalizedFlowDataLoginTerms> -) : Parcelable +import kotlin.math.roundToInt /** * LoginTermsFragment displays the list of policies the user has to accept */ class FtueAuthTermsFragment @Inject constructor( private val policyController: PolicyController -) : AbstractFtueAuthFragment<FragmentLoginTermsBinding>(), +) : AbstractFtueAuthFragment<FragmentFtueLoginTermsBinding>(), PolicyController.PolicyControllerListener { - private val params: FtueAuthTermsFragmentArgument by args() + private val params: FtueAuthTermsLegacyStyleFragmentArgument by args() - override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentLoginTermsBinding { - return FragmentLoginTermsBinding.inflate(inflater, container, false) + override fun getBinding(inflater: LayoutInflater, container: ViewGroup?): FragmentFtueLoginTermsBinding { + return FragmentFtueLoginTermsBinding.inflate(inflater, container, false) } private var loginTermsViewState: LoginTermsViewState = LoginTermsViewState(emptyList()) override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) - setupViews() - views.loginTermsPolicyList.configureWith(policyController) - policyController.listener = this - val list = ArrayList<LocalizedFlowDataLoginTermsChecked>() - params.localizedFlowDataLoginTerms .forEach { list.add(LocalizedFlowDataLoginTermsChecked(it)) } - loginTermsViewState = LoginTermsViewState(list) } private fun setupViews() { - views.loginTermsSubmit.setOnClickListener { submit() } + views.termsSubmit.setOnClickListener { submit() } + views.loginTermsPolicyList.setHasFixedSize(false) + views.loginTermsPolicyList.configureWith(policyController, hasFixedSize = false, dividerDrawable = R.drawable.divider_horizontal) + views.termsGutterStart.doOnLayout { + val gutterSize = views.contentRoot.width * (views.termsGutterStart.layoutParams as ConstraintLayout.LayoutParams).guidePercent + policyController.horizontalPadding = gutterSize.roundToInt() + } + policyController.listener = this } override fun onDestroyView() { @@ -90,7 +88,7 @@ class FtueAuthTermsFragment @Inject constructor( policyController.setData(loginTermsViewState.localizedFlowDataLoginTermsChecked) // Button is enabled only if all checkboxes are checked - views.loginTermsSubmit.isEnabled = loginTermsViewState.allChecked() + views.termsSubmit.isEnabled = loginTermsViewState.allChecked() } override fun setChecked(localizedFlowDataLoginTerms: LocalizedFlowDataLoginTerms, isChecked: Boolean) { @@ -116,7 +114,7 @@ class FtueAuthTermsFragment @Inject constructor( } override fun updateWithState(state: OnboardingViewState) { - policyController.homeServer = state.homeServerUrlFromUser.toReducedUrl() + policyController.homeServer = state.selectedHomeserver.userFacingUrl.toReducedUrl() renderState() } diff --git a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt index 999a7df12a..b9dd40cf41 100755 --- a/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt +++ b/vector/src/main/java/im/vector/app/features/rageshake/BugReporter.kt @@ -53,8 +53,8 @@ import org.json.JSONException import org.json.JSONObject import org.matrix.android.sdk.api.Matrix import org.matrix.android.sdk.api.util.JsonDict +import org.matrix.android.sdk.api.util.MatrixJsonParser import org.matrix.android.sdk.api.util.MimeTypes -import org.matrix.android.sdk.internal.di.MoshiProvider import timber.log.Timber import java.io.File import java.io.IOException @@ -102,7 +102,7 @@ class BugReporter @Inject constructor( // boolean to cancel the bug report private val mIsCancelled = false - val adapter = MoshiProvider.providesMoshi() + val adapter = MatrixJsonParser.getMoshi() .adapter<JsonDict>(Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)) /** diff --git a/vector/src/main/java/im/vector/app/features/raw/wellknown/ElementWellKnownMapper.kt b/vector/src/main/java/im/vector/app/features/raw/wellknown/ElementWellKnownMapper.kt index 899a7d3fe6..06661cb929 100644 --- a/vector/src/main/java/im/vector/app/features/raw/wellknown/ElementWellKnownMapper.kt +++ b/vector/src/main/java/im/vector/app/features/raw/wellknown/ElementWellKnownMapper.kt @@ -18,11 +18,11 @@ package im.vector.app.features.raw.wellknown import com.squareup.moshi.JsonAdapter import org.matrix.android.sdk.api.extensions.tryOrNull -import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.api.util.MatrixJsonParser object ElementWellKnownMapper { - val adapter: JsonAdapter<ElementWellKnown> = MoshiProvider.providesMoshi().adapter(ElementWellKnown::class.java) + val adapter: JsonAdapter<ElementWellKnown> = MatrixJsonParser.getMoshi().adapter(ElementWellKnown::class.java) fun from(value: String): ElementWellKnown? { return tryOrNull("Unable to parse well-known data") { adapter.fromJson(value) } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt index d9ed6d227a..5fee420b21 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileFragment.kt @@ -47,6 +47,8 @@ import im.vector.app.databinding.DialogBaseEditTextBinding import im.vector.app.databinding.DialogShareQrCodeBinding import im.vector.app.databinding.FragmentMatrixProfileBinding import im.vector.app.databinding.ViewStubRoomMemberProfileHeaderBinding +import im.vector.app.features.MainActivity +import im.vector.app.features.MainActivityArgs import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.crypto.verification.VerificationBottomSheet import im.vector.app.features.displayname.getBestName @@ -57,7 +59,7 @@ import im.vector.app.features.home.room.detail.timeline.helper.MatrixItemColorPr import im.vector.app.features.roommemberprofile.devices.DeviceListBottomSheet import im.vector.app.features.roommemberprofile.powerlevel.EditPowerLevelDialogs import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.room.powerlevels.Role import org.matrix.android.sdk.api.util.MatrixItem import javax.inject.Inject @@ -131,13 +133,20 @@ class RoomMemberProfileFragment @Inject constructor( is RoomMemberProfileViewEvents.OnKickActionSuccess -> Unit is RoomMemberProfileViewEvents.OnSetPowerLevelSuccess -> Unit is RoomMemberProfileViewEvents.OnBanActionSuccess -> Unit - is RoomMemberProfileViewEvents.OnIgnoreActionSuccess -> Unit + is RoomMemberProfileViewEvents.OnIgnoreActionSuccess -> handleOnIgnoreActionSuccess(it) is RoomMemberProfileViewEvents.OnInviteActionSuccess -> Unit } } setupLongClicks() } + private fun handleOnIgnoreActionSuccess(action: RoomMemberProfileViewEvents.OnIgnoreActionSuccess) { + if (action.shouldPerformInitialSync) { + // A user has been un-ignored, perform a initial sync + MainActivity.restartApp(requireActivity(), MainActivityArgs(clearCache = true)) + } + } + private fun setupLongClicks() { headerViews.memberProfileNameView.copyOnLongClick() headerViews.memberProfileIdView.copyOnLongClick() diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewEvents.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewEvents.kt index efe23eeff0..1857f5cdc4 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewEvents.kt @@ -25,7 +25,7 @@ sealed class RoomMemberProfileViewEvents : VectorViewEvents { data class Loading(val message: CharSequence? = null) : RoomMemberProfileViewEvents() data class Failure(val throwable: Throwable) : RoomMemberProfileViewEvents() - object OnIgnoreActionSuccess : RoomMemberProfileViewEvents() + data class OnIgnoreActionSuccess(val shouldPerformInitialSync: Boolean) : RoomMemberProfileViewEvents() object OnSetPowerLevelSuccess : RoomMemberProfileViewEvents() object OnInviteActionSuccess : RoomMemberProfileViewEvents() object OnKickActionSuccess : RoomMemberProfileViewEvents() diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt index 1f23fec327..addc2c71ef 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/RoomMemberProfileViewModel.kt @@ -55,7 +55,7 @@ import org.matrix.android.sdk.api.session.room.model.RoomEncryptionAlgorithm import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.room.powerlevels.Role -import org.matrix.android.sdk.api.util.MatrixItem +import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.api.util.toOptional import org.matrix.android.sdk.flow.flow @@ -112,8 +112,8 @@ class RoomMemberProfileViewModel @AssistedInject constructor( session.flow().liveUserCryptoDevices(initialState.userId) .map { Pair( - it.fold(true, { prev, dev -> prev && dev.isVerified }), - it.fold(true, { prev, dev -> prev && (dev.trustLevel?.crossSigningVerified == true) }) + it.fold(true) { prev, dev -> prev && dev.isVerified }, + it.fold(true) { prev, dev -> prev && (dev.trustLevel?.crossSigningVerified == true) } ) } .execute { it -> @@ -327,14 +327,9 @@ class RoomMemberProfileViewModel @AssistedInject constructor( private suspend fun fetchProfileInfo() { val result = runCatchingToAsync { - session.getProfileAsUser(initialState.userId) - .let { - MatrixItem.UserItem( - id = initialState.userId, - displayName = it.displayName, - avatarUrl = it.avatarUrl - ) - } + session.getProfile(initialState.userId) + .let { User.fromJson(initialState.userId, it) } + .toMatrixItem() } setState { @@ -395,7 +390,7 @@ class RoomMemberProfileViewModel @AssistedInject constructor( } else { session.ignoreUserIds(listOf(state.userId)) } - RoomMemberProfileViewEvents.OnIgnoreActionSuccess + RoomMemberProfileViewEvents.OnIgnoreActionSuccess(isIgnored) } catch (failure: Throwable) { RoomMemberProfileViewEvents.Failure(failure) } diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListAction.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListAction.kt index fc28b68b79..c269a4166a 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListAction.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListAction.kt @@ -17,7 +17,7 @@ package im.vector.app.features.roommemberprofile.devices import im.vector.app.core.platform.VectorViewModelAction -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo sealed class DeviceListAction : VectorViewModelAction { data class SelectDevice(val device: CryptoDeviceInfo) : DeviceListAction() diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt index 03e07a2f82..5c64232a5a 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListBottomSheetViewModel.kt @@ -31,11 +31,11 @@ import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.crypto.crosssigning.MXCrossSigningInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.util.MatrixItem import org.matrix.android.sdk.api.util.toMatrixItem import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo data class DeviceListViewState( val userId: String, diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListEpoxyController.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListEpoxyController.kt index 3bfb210f8d..6a9d053d2a 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListEpoxyController.kt @@ -34,7 +34,7 @@ import im.vector.app.core.utils.DimensionConverter import im.vector.app.features.settings.VectorPreferences import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import me.gujun.android.span.span -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import javax.inject.Inject class DeviceListEpoxyController @Inject constructor(private val stringProvider: StringProvider, diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListFragment.kt index dbf1f19595..48a8a819bc 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceListFragment.kt @@ -27,7 +27,7 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.DimensionConverter import im.vector.app.databinding.BottomSheetGenericListBinding -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import javax.inject.Inject class DeviceListFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt index f82ecb6ddf..a733197372 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoActionFragment.kt @@ -27,7 +27,7 @@ import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.core.utils.DimensionConverter import im.vector.app.databinding.BottomSheetGenericListBinding -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import javax.inject.Inject class DeviceTrustInfoActionFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt index c7f6e64f5c..a52f56870a 100644 --- a/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/roommemberprofile/devices/DeviceTrustInfoEpoxyController.kt @@ -29,7 +29,7 @@ import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationA import im.vector.app.features.settings.VectorPreferences import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import me.gujun.android.span.span -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import javax.inject.Inject class DeviceTrustInfoEpoxyController @Inject constructor(private val stringProvider: StringProvider, diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt index 25ba2d9c1a..f937099758 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileController.kt @@ -34,7 +34,7 @@ import im.vector.app.features.settings.VectorPreferences import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import me.gujun.android.span.image import me.gujun.android.span.span -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.room.model.RoomEncryptionAlgorithm import org.matrix.android.sdk.api.session.room.model.RoomSummary import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt index 9177f843a0..3944066584 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/RoomProfileFragment.kt @@ -54,7 +54,6 @@ import im.vector.app.features.home.room.list.actions.RoomListQuickActionsSharedA import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.parcelize.Parcelize -import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.session.room.notification.RoomNotificationState import org.matrix.android.sdk.api.util.toMatrixItem import timber.log.Timber @@ -69,7 +68,6 @@ class RoomProfileFragment @Inject constructor( private val roomProfileController: RoomProfileController, private val avatarRenderer: AvatarRenderer, private val roomDetailPendingActionStore: RoomDetailPendingActionStore, - private val matrixConfiguration: MatrixConfiguration ) : VectorBaseFragment<FragmentMatrixProfileBinding>(), RoomProfileController.Callback { @@ -224,7 +222,7 @@ class RoomProfileFragment @Inject constructor( avatarRenderer.render(matrixItem, views.matrixProfileToolbarAvatarImageView) headerViews.roomProfileDecorationImageView.render(it.roomEncryptionTrustLevel) views.matrixProfileDecorationToolbarAvatarImageView.render(it.roomEncryptionTrustLevel) - headerViews.roomProfilePresenceImageView.render(it.isDirect && matrixConfiguration.presenceSyncEnabled, it.directUserPresence) + headerViews.roomProfilePresenceImageView.render(it.isDirect, it.directUserPresence) headerViews.roomProfilePublicImageView.isVisible = it.isPublic && !it.isDirect } } diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt index 964b081bb7..ea6d6c8b3e 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListController.kt @@ -27,7 +27,6 @@ import im.vector.app.core.resources.ColorProvider import im.vector.app.core.resources.StringProvider import im.vector.app.features.home.AvatarRenderer import me.gujun.android.span.span -import org.matrix.android.sdk.api.MatrixConfiguration import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary @@ -40,8 +39,7 @@ class RoomMemberListController @Inject constructor( private val avatarRenderer: AvatarRenderer, private val stringProvider: StringProvider, private val colorProvider: ColorProvider, - private val roomMemberSummaryFilter: RoomMemberSummaryFilter, - private val matrixConfiguration: MatrixConfiguration + private val roomMemberSummaryFilter: RoomMemberSummaryFilter ) : TypedEpoxyController<RoomMemberListViewState>() { interface Callback { @@ -130,7 +128,6 @@ class RoomMemberListController @Inject constructor( host: RoomMemberListController, data: RoomMemberListViewState) { val powerLabel = stringProvider.getString(powerLevelCategory.titleRes) - val presenceSyncEnabled = matrixConfiguration.presenceSyncEnabled profileMatrixItemWithPowerLevelWithPresence { id(roomMember.userId) @@ -140,7 +137,7 @@ class RoomMemberListController @Inject constructor( clickListener { host.callback?.onRoomMemberClicked(roomMember) } - showPresence(presenceSyncEnabled) + showPresence(true) userPresence(roomMember.userPresence) powerLevelLabel( span { diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt index 0af2303563..1b9be076cd 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewModel.kt @@ -33,10 +33,10 @@ import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.extensions.orFalse import org.matrix.android.sdk.api.query.QueryStringValue import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.events.model.EventType import org.matrix.android.sdk.api.session.events.model.toModel import org.matrix.android.sdk.api.session.room.members.roomMemberQueryParams diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewState.kt b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewState.kt index 9286697496..e385b56cc1 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewState.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/members/RoomMemberListViewState.kt @@ -23,7 +23,7 @@ import com.airbnb.mvrx.Uninitialized import im.vector.app.R import im.vector.app.core.platform.GenericIdArgs import im.vector.app.features.roomprofile.RoomProfileArgs -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.room.model.RoomMemberSummary import org.matrix.android.sdk.api.session.room.model.RoomSummary diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt index 59b66603df..99701f08c3 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/RoomUploadsMediaFragment.kt @@ -46,11 +46,11 @@ import im.vector.app.features.roomprofile.uploads.RoomUploadsAction import im.vector.app.features.roomprofile.uploads.RoomUploadsFragment import im.vector.app.features.roomprofile.uploads.RoomUploadsViewModel import im.vector.app.features.roomprofile.uploads.RoomUploadsViewState +import org.matrix.android.sdk.api.session.crypto.attachments.toElementToDecrypt import org.matrix.android.sdk.api.session.room.model.message.MessageImageContent import org.matrix.android.sdk.api.session.room.model.message.MessageVideoContent import org.matrix.android.sdk.api.session.room.model.message.getFileUrl import org.matrix.android.sdk.api.session.room.model.message.getThumbnailUrl -import org.matrix.android.sdk.internal.crypto.attachments.toElementToDecrypt import javax.inject.Inject class RoomUploadsMediaFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/UploadsMediaController.kt b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/UploadsMediaController.kt index 0a5f498b9d..94d29b3078 100644 --- a/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/UploadsMediaController.kt +++ b/vector/src/main/java/im/vector/app/features/roomprofile/uploads/media/UploadsMediaController.kt @@ -26,13 +26,13 @@ import im.vector.app.core.utils.DimensionConverter import im.vector.app.features.media.ImageContentRenderer import im.vector.app.features.media.VideoContentRenderer import im.vector.app.features.roomprofile.uploads.RoomUploadsViewState +import org.matrix.android.sdk.api.session.crypto.attachments.toElementToDecrypt import org.matrix.android.sdk.api.session.room.model.message.MessageImageContent import org.matrix.android.sdk.api.session.room.model.message.MessageType import org.matrix.android.sdk.api.session.room.model.message.MessageVideoContent import org.matrix.android.sdk.api.session.room.model.message.getFileUrl import org.matrix.android.sdk.api.session.room.model.message.getThumbnailUrl import org.matrix.android.sdk.api.session.room.uploads.UploadEvent -import org.matrix.android.sdk.internal.crypto.attachments.toElementToDecrypt import javax.inject.Inject class UploadsMediaController @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/session/VectorSessionStore.kt b/vector/src/main/java/im/vector/app/features/session/VectorSessionStore.kt index a2f3196979..79183e1808 100644 --- a/vector/src/main/java/im/vector/app/features/session/VectorSessionStore.kt +++ b/vector/src/main/java/im/vector/app/features/session/VectorSessionStore.kt @@ -22,7 +22,7 @@ import androidx.datastore.preferences.core.stringPreferencesKey import im.vector.app.core.extensions.dataStoreProvider import im.vector.app.features.onboarding.FtueUseCase import kotlinx.coroutines.flow.first -import org.matrix.android.sdk.internal.util.md5 +import org.matrix.android.sdk.api.util.md5 /** * User session scoped storage for: diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt index 0d0e322a54..67fa1f5503 100755 --- a/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorPreferences.kt @@ -108,6 +108,7 @@ class VectorPreferences @Inject constructor(private val context: Context, privat private const val SETTINGS_ENABLE_CHAT_EFFECTS = "SETTINGS_ENABLE_CHAT_EFFECTS" private const val SETTINGS_SHOW_EMOJI_KEYBOARD = "SETTINGS_SHOW_EMOJI_KEYBOARD" private const val SETTINGS_LABS_ENABLE_LATEX_MATHS = "SETTINGS_LABS_ENABLE_LATEX_MATHS" + const val SETTINGS_PRESENCE_USER_ALWAYS_APPEARS_OFFLINE = "SETTINGS_PRESENCE_USER_ALWAYS_APPEARS_OFFLINE" // Room directory private const val SETTINGS_ROOM_DIRECTORY_SHOW_ALL_PUBLIC_ROOMS = "SETTINGS_ROOM_DIRECTORY_SHOW_ALL_PUBLIC_ROOMS" @@ -913,6 +914,16 @@ class VectorPreferences @Inject constructor(private val context: Context, privat return bubbleThemeUtils.getBubbleStyle() == BubbleThemeUtils.BUBBLE_STYLE_ELEMENT } + /** + * Tells if user should always appear offline or not. + * + * @return true if user should always appear offline + */ + fun userAlwaysAppearsOffline(): Boolean { + return defaultPrefs.getBoolean(SETTINGS_PRESENCE_USER_ALWAYS_APPEARS_OFFLINE, + getDefault(R.bool.settings_presence_user_always_appears_offline_default)) + } + /** * Update the rage shake enabled status. * diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsLabsFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsLabsFragment.kt index 76862ccb2d..808bf9a6cd 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsLabsFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsLabsFragment.kt @@ -18,19 +18,24 @@ package im.vector.app.features.settings import android.os.Build import android.os.Bundle +import android.text.method.LinkMovementMethod +import android.widget.TextView import androidx.preference.Preference +import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.R import im.vector.app.core.preference.VectorSwitchPreference import im.vector.app.features.MainActivity import im.vector.app.features.MainActivityArgs import im.vector.app.features.analytics.plan.MobileScreen +import im.vector.app.features.home.room.threads.ThreadsManager import im.vector.app.features.themes.ThemeUtils -import org.matrix.android.sdk.internal.database.lightweight.LightweightSettingsStorage +import org.matrix.android.sdk.api.settings.LightweightSettingsStorage import javax.inject.Inject class VectorSettingsLabsFragment @Inject constructor( private val vectorPreferences: VectorPreferences, - private val lightweightSettingsStorage: LightweightSettingsStorage + private val lightweightSettingsStorage: LightweightSettingsStorage, + private val threadsManager: ThreadsManager ) : VectorSettingsBaseFragment() { override var titleRes = R.string.room_settings_labs_pref_title @@ -74,15 +79,51 @@ class VectorSettingsLabsFragment @Inject constructor( } // clear cache - findPreference<VectorSwitchPreference>(VectorPreferences.SETTINGS_LABS_ENABLE_THREAD_MESSAGES)?.let { - it.onPreferenceClickListener = Preference.OnPreferenceClickListener { - // We should migrate threads only if threads are disabled - vectorPreferences.setShouldMigrateThreads(!vectorPreferences.areThreadMessagesEnabled()) - lightweightSettingsStorage.setThreadMessagesEnabled(vectorPreferences.areThreadMessagesEnabled()) - displayLoadingView() - MainActivity.restartApp(requireActivity(), MainActivityArgs(clearCache = true)) + findPreference<VectorSwitchPreference>(VectorPreferences.SETTINGS_LABS_ENABLE_THREAD_MESSAGES)?.let { vectorPref -> + vectorPref.onPreferenceClickListener = Preference.OnPreferenceClickListener { + onThreadsPreferenceClickedInterceptor(vectorPref) false } } } + + /** + * Intercept the click to display a user friendly dialog when their homeserver do not support threads + */ + private fun onThreadsPreferenceClickedInterceptor(vectorSwitchPreference: VectorSwitchPreference) { + val userEnabledThreads = vectorPreferences.areThreadMessagesEnabled() + if (!session.getHomeServerCapabilities().canUseThreading && userEnabledThreads) { + activity?.let { + MaterialAlertDialogBuilder(it) + .setTitle(R.string.threads_labs_enable_notice_title) + .setMessage(threadsManager.getLabsEnableThreadsMessage()) + .setCancelable(true) + .setNegativeButton(R.string.action_not_now) { _, _ -> + vectorSwitchPreference.isChecked = false + } + .setPositiveButton(R.string.action_try_it_out) { _, _ -> + onThreadsPreferenceClicked() + } + .show() + ?.findViewById<TextView>(android.R.id.message) + ?.apply { + linksClickable = true + movementMethod = LinkMovementMethod.getInstance() + } + } + } else { + onThreadsPreferenceClicked() + } + } + + /** + * Action when threads preference switch is actually clicked + */ + private fun onThreadsPreferenceClicked() { + // We should migrate threads only if threads are disabled + vectorPreferences.setShouldMigrateThreads(!vectorPreferences.areThreadMessagesEnabled()) + lightweightSettingsStorage.setThreadMessagesEnabled(vectorPreferences.areThreadMessagesEnabled()) + displayLoadingView() + MainActivity.restartApp(requireActivity(), MainActivityArgs(clearCache = true)) + } } diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt index a34c840dfe..e48e1346c4 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsPreferencesFragment.kt @@ -21,6 +21,7 @@ import android.content.Context import android.os.Bundle import android.widget.CheckedTextView import androidx.core.view.children +import androidx.lifecycle.lifecycleScope import androidx.preference.Preference import com.google.android.material.dialog.MaterialAlertDialogBuilder import im.vector.app.BuildConfig @@ -37,6 +38,8 @@ import im.vector.app.features.analytics.plan.MobileScreen import im.vector.app.features.configuration.VectorConfiguration import im.vector.app.features.themes.BubbleThemeUtils import im.vector.app.features.themes.ThemeUtils +import kotlinx.coroutines.launch +import org.matrix.android.sdk.api.session.presence.model.PresenceEnum import javax.inject.Inject class VectorSettingsPreferencesFragment @Inject constructor( @@ -119,6 +122,17 @@ class VectorSettingsPreferencesFragment @Inject constructor( bubbleAppearancePref = findPreference(BUBBLE_APPEARANCE_KEY) updateBubbleDependencies(bubbleStyle = bubbleStylePreference.value) + findPreference<VectorSwitchPreference>(VectorPreferences.SETTINGS_PRESENCE_USER_ALWAYS_APPEARS_OFFLINE)!!.let { pref -> + pref.isChecked = vectorPreferences.userAlwaysAppearsOffline() + pref.setOnPreferenceChangeListener { _, newValue -> + val presenceOfflineModeEnabled = newValue as? Boolean ?: false + lifecycleScope.launch { + session.setMyPresence(if (presenceOfflineModeEnabled) PresenceEnum.OFFLINE else PresenceEnum.ONLINE) + } + true + } + } + findPreference<VectorSwitchPreference>(VectorPreferences.SETTINGS_PREF_SPACE_SHOW_ALL_ROOM_IN_HOME)!!.let { pref -> pref.isChecked = vectorPreferences.prefSpacesShowAllRoomInHome() pref.setOnPreferenceChangeListener { _, _ -> diff --git a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt index ef87d908ea..1581bb4676 100644 --- a/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/VectorSettingsSecurityPrivacyFragment.kt @@ -73,9 +73,9 @@ import me.gujun.android.span.span import org.matrix.android.sdk.api.MatrixCallback import org.matrix.android.sdk.api.extensions.getFingerprintHumanReadable import org.matrix.android.sdk.api.raw.RawService -import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.DevicesListResponse +import org.matrix.android.sdk.api.session.crypto.crosssigning.isVerified +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DevicesListResponse import javax.inject.Inject class VectorSettingsSecurityPrivacyFragment @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt index 964219ce23..95537a8700 100644 --- a/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/account/deactivation/DeactivateAccountViewModel.kt @@ -31,8 +31,8 @@ import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.failure.isInvalidUIAAuth import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth +import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth +import org.matrix.android.sdk.api.util.fromBase64 import timber.log.Timber import kotlin.coroutines.Continuation import kotlin.coroutines.resume diff --git a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt index 5e691f64b2..0d4c39a230 100644 --- a/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/crosssigning/CrossSigningSettingsViewModel.kt @@ -36,11 +36,11 @@ import org.matrix.android.sdk.api.auth.data.LoginFlowTypes import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.crosssigning.isVerified +import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth +import org.matrix.android.sdk.api.util.awaitCallback +import org.matrix.android.sdk.api.util.fromBase64 import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.crosssigning.isVerified -import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth -import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber import kotlin.coroutines.Continuation import kotlin.coroutines.resume diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceItem.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceItem.kt index ad8cdb7791..b0f6261424 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceItem.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceItem.kt @@ -31,8 +31,8 @@ import im.vector.app.core.resources.ColorProvider import im.vector.app.core.ui.views.ShieldImageView import im.vector.app.core.utils.DimensionConverter import me.gujun.android.span.span -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo /** * A list item for Device. diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt index 2b8fa4b49a..8f04534440 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetController.kt @@ -28,7 +28,7 @@ import im.vector.app.core.ui.views.toDrawableRes import im.vector.app.features.crypto.verification.epoxy.bottomSheetVerificationActionItem import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import org.matrix.android.sdk.api.extensions.orFalse -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo import timber.log.Timber import javax.inject.Inject diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt index 3a944b5a71..2573a2f395 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewModel.kt @@ -27,8 +27,8 @@ import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.flow.map import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo class DeviceVerificationInfoBottomSheetViewModel @AssistedInject constructor(@Assisted initialState: DeviceVerificationInfoBottomSheetViewState, val session: Session diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt index 32927ca068..d0c236d119 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DeviceVerificationInfoBottomSheetViewState.kt @@ -19,8 +19,8 @@ package im.vector.app.features.settings.devices import com.airbnb.mvrx.Async import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.Uninitialized -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo data class DeviceVerificationInfoBottomSheetViewState( val deviceId: String, diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesAction.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesAction.kt index e402982d97..dd8fca3820 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesAction.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesAction.kt @@ -17,7 +17,7 @@ package im.vector.app.features.settings.devices import im.vector.app.core.platform.VectorViewModelAction -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo sealed class DevicesAction : VectorViewModelAction { object Refresh : DevicesAction() diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesController.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesController.kt index ab63ad0894..2659ff4966 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesController.kt @@ -32,8 +32,8 @@ import im.vector.app.core.resources.StringProvider import im.vector.app.core.ui.list.genericHeaderItem import im.vector.app.core.utils.DimensionConverter import im.vector.app.features.settings.VectorPreferences -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo import javax.inject.Inject class DevicesController @Inject constructor(private val errorFormatter: ErrorFormatter, diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewEvents.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewEvents.kt index 9e1f83582f..941b33a8ef 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewEvents.kt @@ -20,8 +20,8 @@ package im.vector.app.features.settings.devices import im.vector.app.core.platform.VectorViewEvents import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo /** * Transient events for Ignored users screen diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt index 76e82e69f6..46a2ba03b1 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/DevicesViewModel.kt @@ -53,17 +53,17 @@ import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.auth.registration.nextUncompletedStage import org.matrix.android.sdk.api.failure.Failure import org.matrix.android.sdk.api.session.Session +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo import org.matrix.android.sdk.api.session.crypto.verification.VerificationMethod import org.matrix.android.sdk.api.session.crypto.verification.VerificationService import org.matrix.android.sdk.api.session.crypto.verification.VerificationTransaction import org.matrix.android.sdk.api.session.crypto.verification.VerificationTxState +import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth +import org.matrix.android.sdk.api.util.awaitCallback +import org.matrix.android.sdk.api.util.fromBase64 import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo -import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo -import org.matrix.android.sdk.internal.util.awaitCallback import timber.log.Timber import javax.net.ssl.HttpsURLConnection import kotlin.coroutines.Continuation diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt b/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt index 06ef96daf7..eadf020f7e 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/TrustUtils.kt @@ -16,8 +16,8 @@ package im.vector.app.features.settings.devices -import org.matrix.android.sdk.api.crypto.RoomEncryptionTrustLevel -import org.matrix.android.sdk.internal.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.crosssigning.DeviceTrustLevel +import org.matrix.android.sdk.api.session.crypto.model.RoomEncryptionTrustLevel object TrustUtils { diff --git a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt index 407af19151..e897cdccac 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devices/VectorSettingsDevicesFragment.kt @@ -39,7 +39,7 @@ import im.vector.app.databinding.FragmentGenericRecyclerBinding import im.vector.app.features.auth.ReAuthActivity import im.vector.app.features.crypto.verification.VerificationBottomSheet import org.matrix.android.sdk.api.auth.data.LoginFlowTypes -import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.DeviceInfo import javax.inject.Inject /** diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt index bce15bbf4b..740ef3996a 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/AccountDataFragment.kt @@ -33,7 +33,7 @@ import im.vector.app.core.utils.createJSonViewerStyleProvider import im.vector.app.databinding.FragmentGenericRecyclerBinding import org.billcarsonfr.jsonviewer.JSonViewerDialog import org.matrix.android.sdk.api.session.accountdata.UserAccountDataEvent -import org.matrix.android.sdk.internal.di.MoshiProvider +import org.matrix.android.sdk.api.util.MatrixJsonParser import javax.inject.Inject class AccountDataFragment @Inject constructor( @@ -70,7 +70,7 @@ class AccountDataFragment @Inject constructor( } override fun didTap(data: UserAccountDataEvent) { - val jsonString = MoshiProvider.providesMoshi() + val jsonString = MatrixJsonParser.getMoshi() .adapter(UserAccountDataEvent::class.java) .toJson(data) JSonViewerDialog.newInstance( diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsSerializer.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsSerializer.kt index d18a6c2ba8..30c2efc3ce 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsSerializer.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingEventsSerializer.kt @@ -18,15 +18,15 @@ package im.vector.app.features.settings.devtools import im.vector.app.core.resources.DateProvider import me.gujun.android.span.span +import org.matrix.android.sdk.api.session.crypto.model.ForwardedRoomKeyContent +import org.matrix.android.sdk.api.session.crypto.model.GossipingToDeviceObject +import org.matrix.android.sdk.api.session.crypto.model.RoomKeyShareRequest +import org.matrix.android.sdk.api.session.crypto.model.SecretShareRequest import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.OlmEventContent +import org.matrix.android.sdk.api.session.events.model.content.SecretSendEventContent import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.internal.crypto.model.event.OlmEventContent -import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent -import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent -import org.matrix.android.sdk.internal.crypto.model.rest.GossipingToDeviceObject -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyShareRequest -import org.matrix.android.sdk.internal.crypto.model.rest.SecretShareRequest import org.threeten.bp.format.DateTimeFormatter class GossipingEventsSerializer { diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingTrailPagedEpoxyController.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingTrailPagedEpoxyController.kt index c1b05cca42..dd016c2bf5 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingTrailPagedEpoxyController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/GossipingTrailPagedEpoxyController.kt @@ -26,15 +26,15 @@ import im.vector.app.core.ui.list.GenericItem_ import im.vector.app.core.utils.createUIHandler import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import me.gujun.android.span.span +import org.matrix.android.sdk.api.session.crypto.model.ForwardedRoomKeyContent +import org.matrix.android.sdk.api.session.crypto.model.GossipingToDeviceObject +import org.matrix.android.sdk.api.session.crypto.model.RoomKeyShareRequest +import org.matrix.android.sdk.api.session.crypto.model.SecretShareRequest import org.matrix.android.sdk.api.session.events.model.Event import org.matrix.android.sdk.api.session.events.model.EventType +import org.matrix.android.sdk.api.session.events.model.content.OlmEventContent +import org.matrix.android.sdk.api.session.events.model.content.SecretSendEventContent import org.matrix.android.sdk.api.session.events.model.toModel -import org.matrix.android.sdk.internal.crypto.model.event.OlmEventContent -import org.matrix.android.sdk.internal.crypto.model.event.SecretSendEventContent -import org.matrix.android.sdk.internal.crypto.model.rest.ForwardedRoomKeyContent -import org.matrix.android.sdk.internal.crypto.model.rest.GossipingToDeviceObject -import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyShareRequest -import org.matrix.android.sdk.internal.crypto.model.rest.SecretShareRequest import javax.inject.Inject class GossipingTrailPagedEpoxyController @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestPagedController.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestPagedController.kt index 4c8bd65c0e..4653f04f2c 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestPagedController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/IncomingKeyRequestPagedController.kt @@ -24,7 +24,7 @@ import im.vector.app.core.ui.list.GenericItem_ import im.vector.app.core.utils.createUIHandler import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import me.gujun.android.span.span -import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.IncomingRoomKeyRequest import javax.inject.Inject class IncomingKeyRequestPagedController @Inject constructor( diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestListViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestListViewModel.kt index 197a72cb05..a8045c07e3 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/KeyRequestListViewModel.kt @@ -32,8 +32,8 @@ import im.vector.app.core.platform.EmptyViewEvents import im.vector.app.core.platform.VectorViewModel import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.internal.crypto.IncomingRoomKeyRequest -import org.matrix.android.sdk.internal.crypto.OutgoingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.IncomingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.OutgoingRoomKeyRequest data class KeyRequestListViewState( val incomingRequests: Async<PagedList<IncomingRoomKeyRequest>> = Uninitialized, diff --git a/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestPagedController.kt b/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestPagedController.kt index 0a52c1a7dd..b23bd77277 100644 --- a/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestPagedController.kt +++ b/vector/src/main/java/im/vector/app/features/settings/devtools/OutgoingKeyRequestPagedController.kt @@ -22,7 +22,7 @@ import im.vector.app.core.ui.list.GenericItem_ import im.vector.app.core.utils.createUIHandler import im.vector.lib.core.utils.epoxy.charsequence.toEpoxyCharSequence import me.gujun.android.span.span -import org.matrix.android.sdk.internal.crypto.OutgoingRoomKeyRequest +import org.matrix.android.sdk.api.session.crypto.model.OutgoingRoomKeyRequest import javax.inject.Inject class OutgoingKeyRequestPagedController @Inject constructor() : PagedListEpoxyController<OutgoingRoomKeyRequest>( diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersAction.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersAction.kt new file mode 100644 index 0000000000..48199e557b --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersAction.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.ignored + +import im.vector.app.core.platform.VectorViewModelAction + +sealed class IgnoredUsersAction : VectorViewModelAction { + data class UnIgnore(val userId: String) : IgnoredUsersAction() +} diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewEvents.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewEvents.kt index 2b2c3eb49d..8d597a9189 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewEvents.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewEvents.kt @@ -25,4 +25,5 @@ import im.vector.app.core.platform.VectorViewEvents sealed class IgnoredUsersViewEvents : VectorViewEvents { data class Loading(val message: CharSequence? = null) : IgnoredUsersViewEvents() data class Failure(val throwable: Throwable) : IgnoredUsersViewEvents() + object Success : IgnoredUsersViewEvents() } diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt index b2a7b2cbd1..14f7cd9230 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewModel.kt @@ -16,37 +16,21 @@ package im.vector.app.features.settings.ignored -import com.airbnb.mvrx.Async -import com.airbnb.mvrx.Fail -import com.airbnb.mvrx.Loading -import com.airbnb.mvrx.MavericksState import com.airbnb.mvrx.MavericksViewModelFactory -import com.airbnb.mvrx.Success -import com.airbnb.mvrx.Uninitialized import dagger.assisted.Assisted import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject import im.vector.app.core.di.MavericksAssistedViewModelFactory import im.vector.app.core.di.hiltMavericksViewModelFactory import im.vector.app.core.platform.VectorViewModel -import im.vector.app.core.platform.VectorViewModelAction import kotlinx.coroutines.launch import org.matrix.android.sdk.api.session.Session -import org.matrix.android.sdk.api.session.user.model.User import org.matrix.android.sdk.flow.flow -data class IgnoredUsersViewState( - val ignoredUsers: List<User> = emptyList(), - val unIgnoreRequest: Async<Unit> = Uninitialized -) : MavericksState - -sealed class IgnoredUsersAction : VectorViewModelAction { - data class UnIgnore(val userId: String) : IgnoredUsersAction() -} - -class IgnoredUsersViewModel @AssistedInject constructor(@Assisted initialState: IgnoredUsersViewState, - private val session: Session) : - VectorViewModel<IgnoredUsersViewState, IgnoredUsersAction, IgnoredUsersViewEvents>(initialState) { +class IgnoredUsersViewModel @AssistedInject constructor( + @Assisted initialState: IgnoredUsersViewState, + private val session: Session +) : VectorViewModel<IgnoredUsersViewState, IgnoredUsersAction, IgnoredUsersViewEvents>(initialState) { @AssistedFactory interface Factory : MavericksAssistedViewModelFactory<IgnoredUsersViewModel, IgnoredUsersViewState> { @@ -76,20 +60,16 @@ class IgnoredUsersViewModel @AssistedInject constructor(@Assisted initialState: } private fun handleUnIgnore(action: IgnoredUsersAction.UnIgnore) { - setState { - copy( - unIgnoreRequest = Loading() - ) - } - + setState { copy(isLoading = true) } viewModelScope.launch { - val result = runCatching { session.unIgnoreUserIds(listOf(action.userId)) } - setState { - copy( - unIgnoreRequest = result.fold(::Success, ::Fail) - ) + val viewEvent = try { + session.unIgnoreUserIds(listOf(action.userId)) + IgnoredUsersViewEvents.Success + } catch (throwable: Throwable) { + IgnoredUsersViewEvents.Failure(throwable) } - result.onFailure { _viewEvents.post(IgnoredUsersViewEvents.Failure(it)) } + setState { copy(isLoading = false) } + _viewEvents.post(viewEvent) } } } diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewState.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewState.kt new file mode 100644 index 0000000000..3dc1bfe795 --- /dev/null +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/IgnoredUsersViewState.kt @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.settings.ignored + +import com.airbnb.mvrx.MavericksState +import org.matrix.android.sdk.api.session.user.model.User + +data class IgnoredUsersViewState( + val ignoredUsers: List<User> = emptyList(), + val isLoading: Boolean = false +) : MavericksState diff --git a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt index 7128639c81..66fa690b82 100644 --- a/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/ignored/VectorSettingsIgnoredUsersFragment.kt @@ -22,8 +22,6 @@ import android.view.View import android.view.ViewGroup import androidx.appcompat.app.AppCompatActivity import androidx.core.view.isVisible -import com.airbnb.mvrx.Async -import com.airbnb.mvrx.Loading import com.airbnb.mvrx.fragmentViewModel import com.airbnb.mvrx.withState import com.google.android.material.dialog.MaterialAlertDialogBuilder @@ -32,6 +30,8 @@ import im.vector.app.core.extensions.cleanup import im.vector.app.core.extensions.configureWith import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentGenericRecyclerBinding +import im.vector.app.features.MainActivity +import im.vector.app.features.MainActivityArgs import im.vector.app.features.analytics.plan.MobileScreen import javax.inject.Inject @@ -62,10 +62,16 @@ class VectorSettingsIgnoredUsersFragment @Inject constructor( when (it) { is IgnoredUsersViewEvents.Loading -> showLoading(it.message) is IgnoredUsersViewEvents.Failure -> showFailure(it.throwable) + IgnoredUsersViewEvents.Success -> handleSuccess() } } } + private fun handleSuccess() { + // A user has been un-ignored, perform a initial sync + MainActivity.restartApp(requireActivity(), MainActivityArgs(clearCache = true)) + } + override fun onDestroyView() { ignoredUsersController.callback = null views.genericRecyclerView.cleanup() @@ -80,11 +86,12 @@ class VectorSettingsIgnoredUsersFragment @Inject constructor( override fun onUserIdClicked(userId: String) { MaterialAlertDialogBuilder(requireActivity()) + .setTitle(R.string.room_participants_action_unignore_title) .setMessage(getString(R.string.settings_unignore_user, userId)) - .setPositiveButton(R.string.yes) { _, _ -> + .setPositiveButton(R.string.unignore) { _, _ -> viewModel.handle(IgnoredUsersAction.UnIgnore(userId)) } - .setNegativeButton(R.string.no, null) + .setNegativeButton(R.string.action_cancel, null) .show() } @@ -94,14 +101,6 @@ class VectorSettingsIgnoredUsersFragment @Inject constructor( override fun invalidate() = withState(viewModel) { state -> ignoredUsersController.update(state) - - handleUnIgnoreRequestStatus(state.unIgnoreRequest) - } - - private fun handleUnIgnoreRequestStatus(unIgnoreRequest: Async<Unit>) { - views.waitingView.root.isVisible = when (unIgnoreRequest) { - is Loading -> true - else -> false - } + views.waitingView.root.isVisible = state.isLoading } } diff --git a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt index c959ae2bf2..f06f6b280a 100644 --- a/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt +++ b/vector/src/main/java/im/vector/app/features/settings/notifications/VectorSettingsNotificationPreferenceFragment.kt @@ -42,6 +42,7 @@ import im.vector.app.core.preference.VectorPreferenceCategory import im.vector.app.core.preference.VectorSwitchPreference import im.vector.app.core.pushers.PushersManager import im.vector.app.core.services.GuardServiceStarter +import im.vector.app.core.utils.combineLatest import im.vector.app.core.utils.isIgnoringBatteryOptimizations import im.vector.app.core.utils.requestDisablingBatteryOptimization import im.vector.app.features.analytics.plan.MobileScreen @@ -61,7 +62,6 @@ import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.identity.ThreePid import org.matrix.android.sdk.api.session.pushers.Pusher import timber.log.Timber -import org.matrix.android.sdk.internal.extensions.combineLatest import javax.inject.Inject // Referenced in vector_settings_preferences_root.xml diff --git a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt index acbe893d58..0af0a8baa5 100644 --- a/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/settings/threepids/ThreePidsSettingsViewModel.kt @@ -36,9 +36,9 @@ import org.matrix.android.sdk.api.auth.UserPasswordAuth import org.matrix.android.sdk.api.auth.registration.RegistrationFlowResponse import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.identity.ThreePid +import org.matrix.android.sdk.api.session.uia.DefaultBaseAuth +import org.matrix.android.sdk.api.util.fromBase64 import org.matrix.android.sdk.flow.flow -import org.matrix.android.sdk.internal.crypto.crosssigning.fromBase64 -import org.matrix.android.sdk.internal.crypto.model.rest.DefaultBaseAuth import timber.log.Timber import kotlin.coroutines.Continuation import kotlin.coroutines.resume diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceBetaHeaderItem.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceBetaHeaderItem.kt index abe7e8d2a8..667f895d4d 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceBetaHeaderItem.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceBetaHeaderItem.kt @@ -16,27 +16,12 @@ package im.vector.app.features.spaces -import android.view.View -import com.airbnb.epoxy.EpoxyAttribute import com.airbnb.epoxy.EpoxyModelClass import im.vector.app.R -import im.vector.app.core.epoxy.ClickListener import im.vector.app.core.epoxy.VectorEpoxyHolder import im.vector.app.core.epoxy.VectorEpoxyModel -import im.vector.app.core.epoxy.onClick @EpoxyModelClass(layout = R.layout.item_space_beta_header) abstract class SpaceBetaHeaderItem : VectorEpoxyModel<SpaceBetaHeaderItem.Holder>() { - - @EpoxyAttribute(EpoxyAttribute.Option.DoNotHash) - var clickAction: ClickListener? = null - - override fun bind(holder: Holder) { - super.bind(holder) - holder.feedBackAction.onClick(clickAction) - } - - class Holder : VectorEpoxyHolder() { - val feedBackAction by bind<View>(R.id.spaceBetaFeedbackAction) - } + class Holder : VectorEpoxyHolder() } diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt index 76d1f93a0e..697bf578ed 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceListViewModel.kt @@ -55,6 +55,7 @@ import org.matrix.android.sdk.api.session.room.RoomSortOrder import org.matrix.android.sdk.api.session.room.accountdata.RoomAccountDataTypes import org.matrix.android.sdk.api.session.room.model.Membership import org.matrix.android.sdk.api.session.room.roomSummaryQueryParams +import org.matrix.android.sdk.api.session.room.spaceSummaryQueryParams import org.matrix.android.sdk.api.session.room.summary.RoomAggregateNotificationCount import org.matrix.android.sdk.api.session.space.SpaceOrderUtils import org.matrix.android.sdk.api.session.space.model.SpaceOrderContent @@ -273,11 +274,9 @@ class SpaceListViewModel @AssistedInject constructor(@Assisted initialState: Spa } private fun observeSpaceSummaries() { - val spaceSummaryQueryParams = roomSummaryQueryParams { + val params = spaceSummaryQueryParams { memberships = listOf(Membership.JOIN, Membership.INVITE) displayName = QueryStringValue.IsNotEmpty - excludeType = listOf(/**RoomType.MESSAGING,$*/ - null) } val flowSession = session.flow() @@ -289,7 +288,7 @@ class SpaceListViewModel @AssistedInject constructor(@Assisted initialState: Spa it.getOrNull() }, flowSession - .liveSpaceSummaries(spaceSummaryQueryParams), + .liveSpaceSummaries(params), session .accountDataService() .getLiveRoomAccountDataEvents(setOf(RoomAccountDataTypes.EVENT_TYPE_SPACE_ORDER)) diff --git a/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt b/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt index 98a0bc228c..77e9577b25 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/SpaceSummaryController.kt @@ -112,9 +112,6 @@ class SpaceSummaryController @Inject constructor( val host = this spaceBetaHeaderItem { id("beta_header") - clickAction { - host.callback?.sendFeedBack() - } } // show invites on top diff --git a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt index 9c6b092135..b03d21e6bd 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/invite/SpaceInviteBottomSheetViewModel.kt @@ -16,7 +16,6 @@ package im.vector.app.features.spaces.invite -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksViewModelFactory diff --git a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomFragment.kt b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomFragment.kt index 8d6a351013..0c4dcbf90f 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomFragment.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/manage/SpaceAddRoomFragment.kt @@ -38,7 +38,6 @@ import im.vector.app.core.platform.OnBackPressed import im.vector.app.core.platform.VectorBaseFragment import im.vector.app.databinding.FragmentSpaceAddRoomsBinding import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.collect import kotlinx.coroutines.flow.debounce import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach diff --git a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt index f5832a8547..23a76b4b68 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/people/SpacePeopleActivity.kt @@ -24,6 +24,7 @@ import androidx.core.view.isVisible import androidx.lifecycle.lifecycleScope import com.airbnb.mvrx.Mavericks import dagger.hilt.android.AndroidEntryPoint +import im.vector.app.R import im.vector.app.core.extensions.hideKeyboard import im.vector.app.core.extensions.replaceFragment import im.vector.app.core.platform.GenericIdArgs @@ -79,7 +80,7 @@ class SpacePeopleActivity : VectorBaseActivity<ActivitySimpleLoadingBinding>() { is SpacePeopleSharedAction.NavigateToRoom -> navigateToRooms(sharedAction) SpacePeopleSharedAction.HideModalLoading -> hideWaitingView() SpacePeopleSharedAction.ShowModalLoading -> { - showWaitingView() + showWaitingView(getString(R.string.please_wait)) } is SpacePeopleSharedAction.NavigateToInvite -> { ShareSpaceBottomSheet.show(supportFragmentManager, sharedAction.spaceId) diff --git a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt index 8d34ad94d8..149f582c5c 100644 --- a/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt +++ b/vector/src/main/java/im/vector/app/features/spaces/preview/SpacePreviewViewModel.kt @@ -16,7 +16,6 @@ package im.vector.app.features.spaces.preview -import androidx.lifecycle.viewModelScope import com.airbnb.mvrx.Fail import com.airbnb.mvrx.Loading import com.airbnb.mvrx.MavericksViewModelFactory @@ -35,8 +34,8 @@ import org.matrix.android.sdk.api.session.Session import org.matrix.android.sdk.api.session.room.model.RoomType import org.matrix.android.sdk.api.session.room.peeking.PeekResult import org.matrix.android.sdk.api.session.space.JoinSpaceResult -import org.matrix.android.sdk.internal.session.space.peeking.SpacePeekResult -import org.matrix.android.sdk.internal.session.space.peeking.SpaceSubChildPeekResult +import org.matrix.android.sdk.api.session.space.peeking.SpacePeekResult +import org.matrix.android.sdk.api.session.space.peeking.SpaceSubChildPeekResult import timber.log.Timber class SpacePreviewViewModel @AssistedInject constructor( diff --git a/vector/src/main/java/im/vector/app/features/voice/AbstractVoiceRecorder.kt b/vector/src/main/java/im/vector/app/features/voice/AbstractVoiceRecorder.kt index c07dde5aeb..14bf09c6c4 100644 --- a/vector/src/main/java/im/vector/app/features/voice/AbstractVoiceRecorder.kt +++ b/vector/src/main/java/im/vector/app/features/voice/AbstractVoiceRecorder.kt @@ -21,7 +21,7 @@ import android.media.MediaRecorder import android.net.Uri import android.os.Build import org.matrix.android.sdk.api.session.content.ContentAttachmentData -import org.matrix.android.sdk.internal.util.md5 +import org.matrix.android.sdk.api.util.md5 import java.io.File import java.io.FileOutputStream import java.util.UUID diff --git a/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt b/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt index cdffbd5411..51e7e6fcb7 100644 --- a/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt +++ b/vector/src/main/java/im/vector/app/features/widgets/WidgetPostAPIHandler.kt @@ -39,8 +39,6 @@ import org.matrix.android.sdk.api.session.room.powerlevels.PowerLevelsHelper import org.matrix.android.sdk.api.session.widgets.WidgetPostAPIMediator import org.matrix.android.sdk.api.util.JsonDict import timber.log.Timber -import java.util.ArrayList -import java.util.HashMap class WidgetPostAPIHandler @AssistedInject constructor(@Assisted private val roomId: String, private val stringProvider: StringProvider, diff --git a/vector/src/main/res/drawable-hdpi/bg_no_location_map.webp b/vector/src/main/res/drawable-hdpi/bg_no_location_map.webp new file mode 100644 index 0000000000..23a45700f0 Binary files /dev/null and b/vector/src/main/res/drawable-hdpi/bg_no_location_map.webp differ diff --git a/vector/src/main/res/drawable-mdpi/bg_no_location_map.webp b/vector/src/main/res/drawable-mdpi/bg_no_location_map.webp new file mode 100644 index 0000000000..a6130fba78 Binary files /dev/null and b/vector/src/main/res/drawable-mdpi/bg_no_location_map.webp differ diff --git a/vector/src/main/res/drawable-xhdpi/bg_no_location_map.webp b/vector/src/main/res/drawable-xhdpi/bg_no_location_map.webp new file mode 100644 index 0000000000..e908191371 Binary files /dev/null and b/vector/src/main/res/drawable-xhdpi/bg_no_location_map.webp differ diff --git a/vector/src/main/res/drawable-xxhdpi/bg_no_location_map.webp b/vector/src/main/res/drawable-xxhdpi/bg_no_location_map.webp new file mode 100644 index 0000000000..e062178367 Binary files /dev/null and b/vector/src/main/res/drawable-xxhdpi/bg_no_location_map.webp differ diff --git a/vector/src/main/res/drawable-xxxhdpi/bg_no_location_map.webp b/vector/src/main/res/drawable-xxxhdpi/bg_no_location_map.webp new file mode 100644 index 0000000000..8b110d33fe Binary files /dev/null and b/vector/src/main/res/drawable-xxxhdpi/bg_no_location_map.webp differ diff --git a/vector/src/main/res/drawable/bg_seek_bar.xml b/vector/src/main/res/drawable/bg_seek_bar.xml new file mode 100644 index 0000000000..0a33522dfd --- /dev/null +++ b/vector/src/main/res/drawable/bg_seek_bar.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:id="@android:id/background"> + <shape + android:shape="line"> + <stroke + android:color="?vctr_content_quaternary" + android:width="2dp"/> + </shape> + </item> + <item android:id="@android:id/progress"> + <clip> + <shape + android:shape="line"> + <stroke + android:color="?vctr_content_tertiary" + android:width="2dp"/> + </shape> + </clip> + </item> +</layer-list> \ No newline at end of file diff --git a/vector/src/main/res/drawable/ic_choose_server.xml b/vector/src/main/res/drawable/ic_choose_server.xml new file mode 100644 index 0000000000..26c8e75222 --- /dev/null +++ b/vector/src/main/res/drawable/ic_choose_server.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="70dp" + android:height="70dp" + android:viewportWidth="70" + android:viewportHeight="70"> + <path + android:pathData="M47.25,36.75H22.75C20.825,36.75 19.25,38.325 19.25,40.25V47.25C19.25,49.175 20.825,50.75 22.75,50.75H47.25C49.175,50.75 50.75,49.175 50.75,47.25V40.25C50.75,38.325 49.175,36.75 47.25,36.75ZM26.25,47.25C24.325,47.25 22.75,45.675 22.75,43.75C22.75,41.825 24.325,40.25 26.25,40.25C28.175,40.25 29.75,41.825 29.75,43.75C29.75,45.675 28.175,47.25 26.25,47.25ZM47.25,19.25H22.75C20.825,19.25 19.25,20.825 19.25,22.75V29.75C19.25,31.675 20.825,33.25 22.75,33.25H47.25C49.175,33.25 50.75,31.675 50.75,29.75V22.75C50.75,20.825 49.175,19.25 47.25,19.25ZM26.25,29.75C24.325,29.75 22.75,28.175 22.75,26.25C22.75,24.325 24.325,22.75 26.25,22.75C28.175,22.75 29.75,24.325 29.75,26.25C29.75,28.175 28.175,29.75 26.25,29.75Z" + android:fillColor="#ff0000"/> +</vector> diff --git a/vector/src/main/res/drawable/ic_ems_logo.xml b/vector/src/main/res/drawable/ic_ems_logo.xml new file mode 100644 index 0000000000..68c2aeb190 --- /dev/null +++ b/vector/src/main/res/drawable/ic_ems_logo.xml @@ -0,0 +1,22 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="50dp" + android:height="50dp" + android:viewportWidth="50" + android:viewportHeight="50"> + <path + android:pathData="M20.43,11.649C20.43,10.64 21.249,9.822 22.26,9.822C29.114,9.822 34.671,15.366 34.671,22.206C34.671,23.215 33.851,24.033 32.84,24.033C31.828,24.033 31.008,23.215 31.008,22.206C31.008,17.385 27.092,13.476 22.26,13.476C21.249,13.476 20.43,12.658 20.43,11.649Z" + android:fillColor="#ffffff" + android:fillType="evenOdd"/> + <path + android:pathData="M38.347,20.379C39.359,20.379 40.178,21.197 40.178,22.206C40.178,29.045 34.622,34.59 27.768,34.59C26.757,34.59 25.937,33.772 25.937,32.763C25.937,31.754 26.757,30.936 27.768,30.936C32.6,30.936 36.516,27.027 36.516,22.206C36.516,21.197 37.336,20.379 38.347,20.379Z" + android:fillColor="#ffffff" + android:fillType="evenOdd"/> + <path + android:pathData="M29.6,38.352C29.6,39.361 28.78,40.18 27.768,40.18C20.915,40.18 15.359,34.635 15.359,27.795C15.359,26.786 16.178,25.968 17.19,25.968C18.201,25.968 19.021,26.786 19.021,27.795C19.021,32.617 22.937,36.525 27.768,36.525C28.78,36.525 29.6,37.343 29.6,38.352Z" + android:fillColor="#ffffff" + android:fillType="evenOdd"/> + <path + android:pathData="M11.653,29.622C10.642,29.622 9.822,28.804 9.822,27.795C9.822,20.956 15.378,15.411 22.232,15.411C23.243,15.411 24.063,16.229 24.063,17.238C24.063,18.247 23.243,19.065 22.232,19.065C17.401,19.065 13.484,22.974 13.484,27.795C13.484,28.804 12.664,29.622 11.653,29.622Z" + android:fillColor="#ffffff" + android:fillType="evenOdd"/> +</vector> diff --git a/vector/src/main/res/drawable/ic_feedback.xml b/vector/src/main/res/drawable/ic_feedback.xml deleted file mode 100644 index e774a8ab5c..0000000000 --- a/vector/src/main/res/drawable/ic_feedback.xml +++ /dev/null @@ -1,14 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="16dp" - android:height="16dp" - android:viewportWidth="16" - android:viewportHeight="16"> - <path - android:pathData="M6.2887,10.748C8.7036,10.748 10.6612,8.7897 10.6612,6.374C10.6612,3.9583 8.7036,2 6.2887,2C3.8739,2 1.9163,3.9583 1.9163,6.374C1.9163,7.038 2.0642,7.6674 2.3288,8.2311L1.6,9.7683C1.2011,10.6099 2.0682,11.492 2.9165,11.1074L4.5258,10.378C5.0651,10.6159 5.6615,10.748 6.2887,10.748Z" - android:fillColor="#368BD6" - android:fillType="evenOdd"/> - <path - android:pathData="M12.6608,7.3739C12.6608,9.7896 10.7032,11.7479 8.2883,11.7479C7.8421,11.7479 7.4114,11.681 7.0059,11.5568C7.7732,12.2953 8.8076,12.7479 9.9456,12.7479C10.5605,12.7479 11.1451,12.6158 11.6737,12.3778L13.211,13.0887C14.0564,13.4796 14.9301,12.6043 14.5376,11.7597L13.8272,10.2308C14.0865,9.6672 14.2315,9.0378 14.2315,8.3739C14.2315,6.4535 13.0188,4.8221 11.3323,4.2339C12.1516,5.0289 12.6608,6.1419 12.6608,7.3739Z" - android:fillColor="#368BD6" - android:fillType="evenOdd"/> -</vector> diff --git a/vector/src/main/res/drawable/ic_headphones.xml b/vector/src/main/res/drawable/ic_headphones.xml deleted file mode 100644 index 86f3d8ab7f..0000000000 --- a/vector/src/main/res/drawable/ic_headphones.xml +++ /dev/null @@ -1,16 +0,0 @@ -<vector xmlns:android="http://schemas.android.com/apk/res/android" - android:width="24dp" - android:height="24dp" - android:viewportWidth="24" - android:viewportHeight="24"> - <path - android:pathData="M3,18V12C3,7.0294 7.0294,3 12,3C16.9706,3 21,7.0294 21,12V18" - android:strokeLineJoin="round" - android:strokeWidth="2" - android:fillColor="#00000000" - android:strokeColor="#2E2F32" - android:strokeLineCap="round"/> - <path - android:pathData="M21,14H22C22,13.4477 21.5523,13 21,13V14ZM3,14V13C2.4477,13 2,13.4477 2,14H3ZM20,19C20,19.5523 19.5523,20 19,20V22C20.6569,22 22,20.6569 22,19H20ZM19,20H18V22H19V20ZM18,20C17.4477,20 17,19.5523 17,19H15C15,20.6569 16.3431,22 18,22V20ZM17,19V16H15V19H17ZM17,16C17,15.4477 17.4477,15 18,15V13C16.3431,13 15,14.3431 15,16H17ZM18,15H21V13H18V15ZM20,14V19H22V14H20ZM2,19C2,20.6569 3.3431,22 5,22V20C4.4477,20 4,19.5523 4,19H2ZM5,22H6V20H5V22ZM6,22C7.6568,22 9,20.6569 9,19H7C7,19.5523 6.5523,20 6,20V22ZM9,19V16H7V19H9ZM9,16C9,14.3431 7.6568,13 6,13V15C6.5523,15 7,15.4477 7,16H9ZM6,13H3V15H6V13ZM2,14V19H4V14H2Z" - android:fillColor="#2E2F32"/> -</vector> diff --git a/vector/src/main/res/drawable/ic_privacy_policy.xml b/vector/src/main/res/drawable/ic_privacy_policy.xml new file mode 100644 index 0000000000..08c63ba44b --- /dev/null +++ b/vector/src/main/res/drawable/ic_privacy_policy.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="71dp" + android:height="70dp" + android:viewportWidth="71" + android:viewportHeight="70"> + <path + android:pathData="M19.778,21.722C19.778,18.501 22.389,15.889 25.611,15.889H45.056C48.277,15.889 50.889,18.501 50.889,21.722V48.944C50.889,52.166 48.277,54.778 45.056,54.778H25.611C22.389,54.778 19.778,52.166 19.778,48.944V21.722ZM25.611,39.708C25.611,38.903 26.264,38.25 27.069,38.25H43.597C44.403,38.25 45.056,38.903 45.056,39.708C45.056,40.514 44.403,41.167 43.597,41.167H27.069C26.264,41.167 25.611,40.514 25.611,39.708ZM27.069,45.056C26.264,45.056 25.611,45.708 25.611,46.514C25.611,47.319 26.264,47.972 27.069,47.972H35.819C36.625,47.972 37.278,47.319 37.278,46.514C37.278,45.708 36.625,45.056 35.819,45.056H27.069Z" + android:fillColor="#ffffff" + android:fillType="evenOdd"/> +</vector> diff --git a/vector/src/main/res/layout/activity_call_transfer.xml b/vector/src/main/res/layout/activity_call_transfer.xml index c3febc96a7..6bf334e62d 100644 --- a/vector/src/main/res/layout/activity_call_transfer.xml +++ b/vector/src/main/res/layout/activity_call_transfer.xml @@ -17,6 +17,7 @@ <com.google.android.material.appbar.MaterialToolbar android:id="@+id/callTransferToolbar" + app:title="@string/call_transfer_title" android:layout_width="match_parent" android:layout_height="wrap_content" /> @@ -86,4 +87,4 @@ layout="@layout/merge_overlay_waiting_view" /> </androidx.constraintlayout.widget.ConstraintLayout> -</androidx.coordinatorlayout.widget.CoordinatorLayout> \ No newline at end of file +</androidx.coordinatorlayout.widget.CoordinatorLayout> diff --git a/vector/src/main/res/layout/fragment_ftue_account_created.xml b/vector/src/main/res/layout/fragment_ftue_account_created.xml index 28d1cb3c2e..85c4ded62c 100644 --- a/vector/src/main/res/layout/fragment_ftue_account_created.xml +++ b/vector/src/main/res/layout/fragment_ftue_account_created.xml @@ -6,12 +6,6 @@ android:layout_height="match_parent" android:background="?colorSecondary"> - <nl.dionsegijn.konfetti.KonfettiView - android:id="@+id/viewKonfetti" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:visibility="gone" /> - <androidx.constraintlayout.widget.Guideline android:id="@+id/ftueAuthGutterStart" android:layout_width="wrap_content" @@ -168,4 +162,10 @@ app:layout_constraintHeight_percent="0.05" app:layout_constraintTop_toBottomOf="@id/ctaBottomBarrier" /> + <nl.dionsegijn.konfetti.xml.KonfettiView + android:id="@+id/viewKonfetti" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:visibility="gone" /> + </androidx.constraintlayout.widget.ConstraintLayout> diff --git a/vector/src/main/res/layout/fragment_ftue_sign_up_combined.xml b/vector/src/main/res/layout/fragment_ftue_combined_register.xml similarity index 98% rename from vector/src/main/res/layout/fragment_ftue_sign_up_combined.xml rename to vector/src/main/res/layout/fragment_ftue_combined_register.xml index 9602dd0231..9d61780ad0 100644 --- a/vector/src/main/res/layout/fragment_ftue_sign_up_combined.xml +++ b/vector/src/main/res/layout/fragment_ftue_combined_register.xml @@ -109,7 +109,6 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="12dp" - android:text="@string/ftue_auth_create_account_matrix_dot_org_server_name" android:textColor="?vctr_content_primary" app:layout_constraintBottom_toTopOf="@id/selectedServerDescription" app:layout_constraintEnd_toStartOf="@id/editServerButton" @@ -122,7 +121,6 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginStart="12dp" - android:text="@string/ftue_auth_create_account_matrix_dot_org_server_description" android:textColor="?vctr_content_tertiary" app:layout_constraintBottom_toTopOf="@id/serverSelectionSpacing" app:layout_constraintEnd_toStartOf="@id/editServerButton" @@ -139,7 +137,6 @@ android:paddingEnd="12dp" android:text="@string/ftue_auth_create_account_edit_server_selection" android:textAllCaps="true" - android:visibility="gone" app:layout_constraintBottom_toBottomOf="@id/selectedServerDescription" app:layout_constraintEnd_toEndOf="@id/createAccountGutterEnd" app:layout_constraintTop_toTopOf="@id/chooseYourServerHeader" /> @@ -176,6 +173,7 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:imeOptions="actionNext" + android:nextFocusForward="@id/createAccountPasswordInput" android:inputType="text" android:maxLines="1" /> diff --git a/vector/src/main/res/layout/fragment_ftue_login_captcha.xml b/vector/src/main/res/layout/fragment_ftue_login_captcha.xml new file mode 100644 index 0000000000..d07e8e2b97 --- /dev/null +++ b/vector/src/main/res/layout/fragment_ftue_login_captcha.xml @@ -0,0 +1,106 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/captchaRoot" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:background="?android:colorBackground"> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/captchaGutterStart" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:orientation="vertical" + app:layout_constraintGuide_percent="@dimen/ftue_auth_gutter_start_percent" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/captchaGutterEnd" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:orientation="vertical" + app:layout_constraintGuide_percent="@dimen/ftue_auth_gutter_end_percent" /> + + <Space + android:id="@+id/headerSpacing" + android:layout_width="match_parent" + android:layout_height="52dp" + app:layout_constraintBottom_toTopOf="@id/captchaHeaderIcon" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0" + app:layout_constraintVertical_chainStyle="packed" /> + + <ImageView + android:id="@+id/captchaHeaderIcon" + android:layout_width="wrap_content" + android:layout_height="0dp" + android:adjustViewBounds="true" + android:background="@drawable/circle" + android:backgroundTint="?colorSecondary" + android:contentDescription="@null" + android:src="@drawable/ic_user_fg" + app:layout_constraintBottom_toTopOf="@id/captchaHeaderTitle" + app:layout_constraintEnd_toEndOf="@id/captchaGutterEnd" + app:layout_constraintHeight_percent="0.10" + app:layout_constraintStart_toStartOf="@id/captchaGutterStart" + app:layout_constraintTop_toBottomOf="@id/headerSpacing" + app:tint="@color/palette_white" /> + + <TextView + android:id="@+id/captchaHeaderTitle" + style="@style/Widget.Vector.TextView.Title.Medium" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:gravity="center" + android:text="@string/ftue_auth_create_account_title" + android:textColor="?vctr_content_primary" + app:layout_constraintBottom_toTopOf="@id/captchaHeaderSubtitle" + app:layout_constraintEnd_toEndOf="@id/captchaGutterEnd" + app:layout_constraintStart_toStartOf="@id/captchaGutterStart" + app:layout_constraintTop_toBottomOf="@id/captchaHeaderIcon" /> + + <TextView + android:id="@+id/captchaHeaderSubtitle" + style="@style/Widget.Vector.TextView.Subtitle" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:gravity="center" + android:text="@string/auth_recaptcha_message" + android:textColor="?vctr_content_secondary" + app:layout_constraintBottom_toTopOf="@id/titleContentSpacing" + app:layout_constraintEnd_toEndOf="@id/captchaGutterEnd" + app:layout_constraintStart_toStartOf="@id/captchaGutterStart" + app:layout_constraintTop_toBottomOf="@id/captchaHeaderTitle" /> + + <Space + android:id="@+id/titleContentSpacing" + android:layout_width="match_parent" + android:layout_height="0dp" + app:layout_constraintBottom_toTopOf="@id/loginCaptchaWevView" + app:layout_constraintHeight_percent="0.03" + app:layout_constraintTop_toBottomOf="@id/captchaHeaderSubtitle" /> + + <WebView + android:id="@+id/loginCaptchaWevView" + android:layout_width="0dp" + android:layout_height="0dp" + android:contentDescription="@string/login_a11y_captcha_container" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="@id/captchaGutterEnd" + app:layout_constraintStart_toStartOf="@id/captchaGutterStart" + app:layout_constraintTop_toBottomOf="@id/titleContentSpacing" /> + + <ProgressBar + android:id="@+id/loginCaptchaProgress" + android:layout_width="60dp" + android:layout_height="60dp" + android:layout_gravity="center" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="@id/captchaGutterEnd" + app:layout_constraintStart_toStartOf="@id/captchaGutterStart" + app:layout_constraintTop_toBottomOf="@id/headerSpacing" + tools:ignore="UnknownId,NotSibling" /> + +</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/vector/src/main/res/layout/fragment_ftue_login_terms.xml b/vector/src/main/res/layout/fragment_ftue_login_terms.xml new file mode 100644 index 0000000000..c388b963d9 --- /dev/null +++ b/vector/src/main/res/layout/fragment_ftue_login_terms.xml @@ -0,0 +1,121 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + style="@style/LoginFormScrollView" + android:layout_height="match_parent" + android:background="?android:colorBackground" + android:fillViewport="true" + android:paddingTop="0dp" + android:paddingBottom="0dp"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/contentRoot" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/termsGutterStart" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:orientation="vertical" + app:layout_constraintGuide_percent="@dimen/ftue_auth_gutter_start_percent" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/termsGutterEnd" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:orientation="vertical" + app:layout_constraintGuide_percent="@dimen/ftue_auth_gutter_end_percent" /> + + <Space + android:id="@+id/headerSpacing" + android:layout_width="match_parent" + android:layout_height="52dp" + app:layout_constraintBottom_toTopOf="@id/termsHeaderIcon" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0" + app:layout_constraintVertical_chainStyle="packed" /> + + <ImageView + android:id="@+id/termsHeaderIcon" + android:layout_width="wrap_content" + android:layout_height="0dp" + android:adjustViewBounds="true" + android:background="@drawable/circle" + android:backgroundTint="?colorSecondary" + android:contentDescription="@null" + android:src="@drawable/ic_privacy_policy" + app:layout_constraintBottom_toTopOf="@id/termsHeaderTitle" + app:layout_constraintEnd_toEndOf="@id/termsGutterEnd" + app:layout_constraintHeight_percent="0.12" + app:layout_constraintStart_toStartOf="@id/termsGutterStart" + app:layout_constraintTop_toBottomOf="@id/headerSpacing" + app:tint="@color/palette_white" /> + + <TextView + android:id="@+id/termsHeaderTitle" + style="@style/Widget.Vector.TextView.Title.Medium" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:gravity="center" + android:text="@string/ftue_auth_terms_title" + android:textColor="?vctr_content_primary" + app:layout_constraintBottom_toTopOf="@id/termsHeaderSubtitle" + app:layout_constraintEnd_toEndOf="@id/termsGutterEnd" + app:layout_constraintStart_toStartOf="@id/termsGutterStart" + app:layout_constraintTop_toBottomOf="@id/termsHeaderIcon" /> + + <TextView + android:id="@+id/termsHeaderSubtitle" + style="@style/Widget.Vector.TextView.Subtitle" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:gravity="center" + android:text="@string/ftue_auth_terms_subtitle" + android:textColor="?vctr_content_secondary" + app:layout_constraintBottom_toTopOf="@id/titleContentSpacing" + app:layout_constraintEnd_toEndOf="@id/termsGutterEnd" + app:layout_constraintStart_toStartOf="@id/termsGutterStart" + app:layout_constraintTop_toBottomOf="@id/termsHeaderTitle" /> + + <Space + android:id="@+id/titleContentSpacing" + android:layout_width="match_parent" + android:layout_height="0dp" + app:layout_constraintBottom_toTopOf="@id/loginTermsPolicyList" + app:layout_constraintHeight_percent="0.03" + app:layout_constraintTop_toBottomOf="@id/termsHeaderSubtitle" /> + + <androidx.recyclerview.widget.RecyclerView + android:id="@+id/loginTermsPolicyList" + android:layout_width="0dp" + android:layout_height="wrap_content" + app:layout_constraintBottom_toTopOf="@id/entrySpacing" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toBottomOf="@id/titleContentSpacing" /> + + <Space + android:id="@+id/entrySpacing" + android:layout_width="match_parent" + android:layout_height="0dp" + app:layout_constraintBottom_toTopOf="@id/termsSubmit" + app:layout_constraintHeight_percent="0.05" + app:layout_constraintTop_toBottomOf="@id/loginTermsPolicyList" /> + + <Button + android:id="@+id/termsSubmit" + style="@style/Widget.Vector.Button.Login" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:text="@string/login_signup_submit" + android:textAllCaps="true" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="@id/termsGutterEnd" + app:layout_constraintStart_toStartOf="@id/termsGutterStart" + app:layout_constraintTop_toBottomOf="@id/entrySpacing" /> + + </androidx.constraintlayout.widget.ConstraintLayout> +</androidx.core.widget.NestedScrollView> diff --git a/vector/src/main/res/layout/fragment_ftue_personalization_complete.xml b/vector/src/main/res/layout/fragment_ftue_personalization_complete.xml index a9d86143fd..f53724551f 100644 --- a/vector/src/main/res/layout/fragment_ftue_personalization_complete.xml +++ b/vector/src/main/res/layout/fragment_ftue_personalization_complete.xml @@ -4,12 +4,6 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - <nl.dionsegijn.konfetti.KonfettiView - android:id="@+id/viewKonfetti" - android:layout_width="match_parent" - android:layout_height="match_parent" - android:visibility="gone" /> - <androidx.constraintlayout.widget.Guideline android:id="@+id/ftueAuthGutterStart" android:layout_width="wrap_content" @@ -112,4 +106,10 @@ app:layout_constraintHeight_percent="0.05" app:layout_constraintTop_toBottomOf="@id/personalizationCompleteCta" /> + <nl.dionsegijn.konfetti.xml.KonfettiView + android:id="@+id/viewKonfetti" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:visibility="gone" /> + </androidx.constraintlayout.widget.ConstraintLayout> diff --git a/vector/src/main/res/layout/fragment_ftue_server_selection_combined.xml b/vector/src/main/res/layout/fragment_ftue_server_selection_combined.xml new file mode 100644 index 0000000000..5a60632e86 --- /dev/null +++ b/vector/src/main/res/layout/fragment_ftue_server_selection_combined.xml @@ -0,0 +1,257 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + style="@style/LoginFormScrollView" + android:layout_height="match_parent" + android:background="?android:colorBackground" + android:fillViewport="true" + android:paddingTop="0dp" + android:paddingBottom="0dp"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/chooseServerRoot" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/chooseServerGutterStart" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:orientation="vertical" + app:layout_constraintGuide_percent="@dimen/ftue_auth_gutter_start_percent" /> + + <androidx.constraintlayout.widget.Guideline + android:id="@+id/chooseServerGutterEnd" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:orientation="vertical" + app:layout_constraintGuide_percent="@dimen/ftue_auth_gutter_end_percent" /> + + <com.google.android.material.appbar.MaterialToolbar + android:id="@+id/chooseServerToolbar" + style="@style/Widget.Vector.Toolbar.Settings" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@android:color/transparent" + app:layout_constraintBottom_toTopOf="@id/chooseServerHeaderIcon" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0" + app:layout_constraintVertical_chainStyle="packed" + app:navigationIcon="@drawable/ic_close_24dp" /> + + <ImageView + android:id="@+id/chooseServerHeaderIcon" + android:layout_width="wrap_content" + android:layout_height="0dp" + android:adjustViewBounds="true" + android:background="@drawable/circle" + android:backgroundTint="?colorSecondary" + android:contentDescription="@null" + android:src="@drawable/ic_choose_server" + app:layout_constraintBottom_toTopOf="@id/chooseServerHeaderTitle" + app:layout_constraintEnd_toEndOf="@id/chooseServerGutterEnd" + app:layout_constraintHeight_percent="0.10" + app:layout_constraintStart_toStartOf="@id/chooseServerGutterStart" + app:layout_constraintTop_toBottomOf="@id/chooseServerToolbar" + app:tint="@color/palette_white" /> + + <TextView + android:id="@+id/chooseServerHeaderTitle" + style="@style/Widget.Vector.TextView.Title.Medium" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="16dp" + android:gravity="center" + android:text="@string/ftue_auth_choose_server_title" + android:textColor="?vctr_content_primary" + app:layout_constraintBottom_toTopOf="@id/chooseServerHeaderSubtitle" + app:layout_constraintEnd_toEndOf="@id/chooseServerGutterEnd" + app:layout_constraintStart_toStartOf="@id/chooseServerGutterStart" + app:layout_constraintTop_toBottomOf="@id/chooseServerHeaderIcon" /> + + <TextView + android:id="@+id/chooseServerHeaderSubtitle" + style="@style/Widget.Vector.TextView.Subtitle" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:gravity="center" + android:text="@string/ftue_auth_choose_server_subtitle" + android:textColor="?vctr_content_secondary" + app:layout_constraintBottom_toTopOf="@id/titleContentSpacing" + app:layout_constraintEnd_toEndOf="@id/chooseServerGutterEnd" + app:layout_constraintStart_toStartOf="@id/chooseServerGutterStart" + app:layout_constraintTop_toBottomOf="@id/chooseServerHeaderTitle" /> + + <Space + android:id="@+id/titleContentSpacing" + android:layout_width="match_parent" + android:layout_height="0dp" + app:layout_constraintBottom_toTopOf="@id/chooseServerInput" + app:layout_constraintHeight_percent="0.03" + app:layout_constraintTop_toBottomOf="@id/chooseServerHeaderSubtitle" /> + + <com.google.android.material.textfield.TextInputLayout + android:id="@+id/chooseServerInput" + style="@style/Widget.Vector.TextInputLayout.Username" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:hint="@string/ftue_auth_choose_server_entry_hint" + app:layout_constraintBottom_toTopOf="@id/chooseServerEntryFooter" + app:layout_constraintEnd_toEndOf="@id/chooseServerGutterEnd" + app:layout_constraintStart_toStartOf="@id/chooseServerGutterStart" + app:layout_constraintTop_toBottomOf="@id/titleContentSpacing"> + + <com.google.android.material.textfield.TextInputEditText + android:layout_width="match_parent" + android:layout_height="match_parent" + android:imeOptions="actionDone" + android:inputType="textUri" + android:maxLines="1" /> + + </com.google.android.material.textfield.TextInputLayout> + + <TextView + android:id="@+id/chooseServerEntryFooter" + style="@style/Widget.Vector.TextView.Micro" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="4dp" + android:text="@string/ftue_auth_choose_server_entry_footer" + app:layout_constraintBottom_toTopOf="@id/actionSpacing" + app:layout_constraintEnd_toEndOf="@id/chooseServerGutterEnd" + app:layout_constraintStart_toStartOf="@id/chooseServerGutterStart" + app:layout_constraintTop_toBottomOf="@id/chooseServerInput" /> + + <Space + android:id="@+id/actionSpacing" + android:layout_width="match_parent" + android:layout_height="0dp" + app:layout_constraintBottom_toTopOf="@id/chooseServerSubmit" + app:layout_constraintHeight_percent="0.02" + app:layout_constraintTop_toBottomOf="@id/chooseServerEntryFooter" /> + + <Button + android:id="@+id/chooseServerSubmit" + style="@style/Widget.Vector.Button.Login" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:text="@string/login_signup_submit" + android:textAllCaps="true" + app:layout_constraintBottom_toTopOf="@id/chooseServerEmsContainer" + app:layout_constraintEnd_toEndOf="@id/chooseServerGutterEnd" + app:layout_constraintStart_toStartOf="@id/chooseServerGutterStart" + app:layout_constraintTop_toBottomOf="@id/actionSpacing" /> + + <Space + android:id="@+id/submitSpacing" + android:layout_width="match_parent" + android:layout_height="0dp" + app:layout_constraintBottom_toTopOf="@id/emsTopSpacing" + app:layout_constraintHeight_percent="0.02" + app:layout_constraintTop_toBottomOf="@id/chooseServerSubmit" /> + + <View + android:id="@+id/chooseServerEmsContainer" + android:layout_width="0dp" + android:layout_height="0dp" + android:background="@drawable/rounded_rect_shape_8" + android:backgroundTint="?vctr_system" + app:layout_constraintBottom_toBottomOf="@id/emsCtaSpacing" + app:layout_constraintEnd_toEndOf="@id/chooseServerGutterEnd" + app:layout_constraintHorizontal_bias="1.0" + app:layout_constraintStart_toStartOf="@id/chooseServerGutterStart" + app:layout_constraintTop_toTopOf="@id/emsTopSpacing" + app:layout_constraintVertical_bias="0.0" /> + + <Space + android:id="@+id/emsTopSpacing" + android:layout_width="match_parent" + android:layout_height="24dp" + app:layout_constraintBottom_toTopOf="@id/chooseServerEmsIcon" + app:layout_constraintTop_toBottomOf="@id/chooseServerSubmit" + app:layout_constraintVertical_bias="1" + app:layout_constraintVertical_chainStyle="packed" /> + + <ImageView + android:id="@+id/chooseServerEmsIcon" + android:layout_width="wrap_content" + android:layout_height="0dp" + android:layout_marginBottom="22dp" + android:adjustViewBounds="true" + android:background="@drawable/circle" + android:backgroundTint="@color/palette_ems" + android:contentDescription="@null" + android:src="@drawable/ic_ems_logo" + app:layout_constraintBottom_toTopOf="@id/chooseServerEmsTitle" + app:layout_constraintEnd_toEndOf="@id/chooseServerGutterEnd" + app:layout_constraintHeight_percent="0.08" + app:layout_constraintStart_toStartOf="@id/chooseServerGutterStart" + app:layout_constraintTop_toBottomOf="@id/emsTopSpacing" + app:layout_constraintVertical_bias="1" + app:tint="@color/palette_white" /> + + <TextView + android:id="@+id/chooseServerEmsTitle" + style="@style/Widget.Vector.TextView.HeadlineMedium" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:layout_marginBottom="12dp" + android:gravity="center" + android:text="@string/ftue_auth_choose_server_ems_title" + app:layout_constraintBottom_toTopOf="@id/chooseServerEmsSubtitle" + app:layout_constraintEnd_toEndOf="@id/chooseServerGutterEnd" + app:layout_constraintStart_toStartOf="@id/chooseServerGutterStart" + app:layout_constraintTop_toBottomOf="@id/chooseServerEmsIcon" /> + + <TextView + android:id="@+id/chooseServerEmsSubtitle" + style="@style/Widget.Vector.TextView.Body" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:layout_marginBottom="16dp" + android:autoLink="web" + android:gravity="center" + android:text="@string/ftue_auth_choose_server_ems_subtitle" + app:layout_constraintBottom_toTopOf="@id/chooseServerGetInTouch" + app:layout_constraintEnd_toEndOf="@id/chooseServerGutterEnd" + app:layout_constraintStart_toStartOf="@id/chooseServerGutterStart" + app:layout_constraintTop_toBottomOf="@id/chooseServerEmsTitle" /> + + <Button + android:id="@+id/chooseServerGetInTouch" + style="@style/Widget.Vector.Button.Login" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="16dp" + android:layout_marginEnd="16dp" + android:backgroundTint="@color/palette_ems" + android:text="@string/ftue_auth_choose_server_ems_cta" + android:textAllCaps="true" + app:layout_constraintBottom_toTopOf="@id/emsCtaSpacing" + app:layout_constraintEnd_toEndOf="@id/chooseServerGutterEnd" + app:layout_constraintStart_toStartOf="@id/chooseServerGutterStart" + app:layout_constraintTop_toBottomOf="@id/chooseServerEmsSubtitle" /> + + <Space + android:id="@+id/emsCtaSpacing" + android:layout_width="match_parent" + android:layout_height="16dp" + app:layout_constraintBottom_toTopOf="@id/footerSpacing" + app:layout_constraintTop_toBottomOf="@id/chooseServerGetInTouch" /> + + <Space + android:id="@+id/footerSpacing" + android:layout_width="match_parent" + android:layout_height="0dp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintHeight_percent="0.03" + app:layout_constraintTop_toBottomOf="@id/emsCtaSpacing" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + +</androidx.core.widget.NestedScrollView> diff --git a/vector/src/main/res/layout/fragment_login_captcha.xml b/vector/src/main/res/layout/fragment_login_captcha.xml index 655bd98097..d7e5e17aa0 100644 --- a/vector/src/main/res/layout/fragment_login_captcha.xml +++ b/vector/src/main/res/layout/fragment_login_captcha.xml @@ -29,7 +29,6 @@ android:text="@string/auth_recaptcha_message" android:textColor="?vctr_content_secondary" /> - <!-- contentDescription does not work on WebView? --> <WebView android:id="@+id/loginCaptchaWevView" android:layout_width="match_parent" diff --git a/vector/src/main/res/layout/fragment_login_terms.xml b/vector/src/main/res/layout/fragment_login_terms.xml index a0af01eda8..51facb0d81 100644 --- a/vector/src/main/res/layout/fragment_login_terms.xml +++ b/vector/src/main/res/layout/fragment_login_terms.xml @@ -48,6 +48,8 @@ android:layout_height="0dp" android:layout_marginTop="10dp" android:layout_marginBottom="16dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" app:layout_constraintBottom_toTopOf="@id/loginTermsSubmit" app:layout_constraintTop_toBottomOf="@id/loginTermsNotice" tools:listitem="@layout/item_policy" /> diff --git a/vector/src/main/res/layout/fragment_login_terms_2.xml b/vector/src/main/res/layout/fragment_login_terms_2.xml index a64ec08184..18b7df3880 100644 --- a/vector/src/main/res/layout/fragment_login_terms_2.xml +++ b/vector/src/main/res/layout/fragment_login_terms_2.xml @@ -52,6 +52,8 @@ android:layout_height="0dp" android:layout_marginTop="10dp" android:layout_marginBottom="16dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" app:layout_constraintBottom_toTopOf="@id/loginTermsSubmit" app:layout_constraintTop_toBottomOf="@id/loginTermsNotice" tools:listitem="@layout/item_policy" /> diff --git a/vector/src/main/res/layout/fragment_timeline.xml b/vector/src/main/res/layout/fragment_timeline.xml index 6421c241a3..a062fe4b9b 100644 --- a/vector/src/main/res/layout/fragment_timeline.xml +++ b/vector/src/main/res/layout/fragment_timeline.xml @@ -203,7 +203,7 @@ app:layout_constraintEnd_toEndOf="parent" app:tint="@android:color/white" /> - <nl.dionsegijn.konfetti.KonfettiView + <nl.dionsegijn.konfetti.xml.KonfettiView android:id="@+id/viewKonfetti" android:layout_width="match_parent" android:layout_height="match_parent" diff --git a/vector/src/main/res/layout/item_policy.xml b/vector/src/main/res/layout/item_policy.xml index 7f4a90b5d0..cf031ad55d 100644 --- a/vector/src/main/res/layout/item_policy.xml +++ b/vector/src/main/res/layout/item_policy.xml @@ -6,24 +6,22 @@ android:layout_height="wrap_content" android:foreground="?attr/selectableItemBackground" android:minHeight="72dp" - android:paddingStart="16dp" - android:paddingEnd="16dp" tools:viewBindingIgnore="true"> <CheckBox android:id="@+id/adapter_item_policy_checkbox" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:buttonTint="@color/checkbox_tint_selector" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/adapter_item_policy_title" - style="@style/Widget.Vector.TextView.Body" + style="@style/Widget.Vector.TextView.Subtitle" android:layout_width="0dp" android:layout_height="wrap_content" - android:drawablePadding="8dp" android:textColor="?vctr_content_primary" app:layout_constraintBottom_toTopOf="@id/adapter_item_policy_subtitle" app:layout_constraintEnd_toStartOf="@id/adapter_item_policy_arrow" @@ -50,16 +48,15 @@ <ImageView android:id="@+id/adapter_item_policy_arrow" android:layout_width="wrap_content" - android:layout_height="wrap_content" + android:layout_height="16dp" + android:adjustViewBounds="true" android:importantForAccessibility="no" - android:paddingStart="8dp" - android:paddingEnd="0dp" android:rotationY="@integer/rtl_mirror_flip" android:src="@drawable/ic_arrow_right" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" - app:tint="?vctr_content_secondary" + app:tint="?vctr_content_tertiary" tools:ignore="MissingPrefix" /> -</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file +</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/vector/src/main/res/layout/item_space_beta_header.xml b/vector/src/main/res/layout/item_space_beta_header.xml index a4990644d0..3ccc541371 100644 --- a/vector/src/main/res/layout/item_space_beta_header.xml +++ b/vector/src/main/res/layout/item_space_beta_header.xml @@ -8,6 +8,7 @@ android:paddingStart="16dp" android:paddingTop="8dp" android:paddingEnd="16dp" + android:paddingBottom="16dp" tools:viewBindingIgnore="true"> <TextView @@ -27,19 +28,4 @@ android:text="@string/spaces_beta_welcome_to_spaces_desc" android:textColor="?vctr_content_secondary" /> - <TextView - android:id="@+id/spaceBetaFeedbackAction" - style="@style/Widget.Vector.TextView.Body" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:drawablePadding="8dp" - android:paddingStart="0dp" - android:paddingTop="8dp" - android:paddingEnd="16dp" - android:paddingBottom="8dp" - android:text="@string/give_feedback" - android:textColor="@color/vector_info_color" - android:visibility="gone" - app:drawableStartCompat="@drawable/ic_feedback" /> - </LinearLayout> diff --git a/vector/src/main/res/layout/item_timeline_event_audio_stub.xml b/vector/src/main/res/layout/item_timeline_event_audio_stub.xml new file mode 100644 index 0000000000..2a6fbf5a9e --- /dev/null +++ b/vector/src/main/res/layout/item_timeline_event_audio_stub.xml @@ -0,0 +1,107 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/messageRootLayout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + tools:viewBindingIgnore="true"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/messageMainInnerLayout" + style="@style/TimelineContentMediaPillStyle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + tools:viewBindingIgnore="true"> + + <ImageButton + android:id="@+id/audioPlaybackControlButton" + android:layout_width="@dimen/item_event_message_media_button_size" + android:layout_height="@dimen/item_event_message_media_button_size" + android:background="@drawable/bg_voice_play_pause_button" + android:backgroundTint="?android:colorBackground" + android:contentDescription="@string/a11y_play_voice_message" + android:src="@drawable/ic_play_pause_play" + android:layout_marginTop="10dp" + android:layout_marginStart="4dp" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:tint="?vctr_content_secondary" /> + + <TextView + android:id="@+id/messageFilenameView" + style="@style/Widget.Vector.TextView.Body" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginStart="8dp" + android:autoLink="none" + android:maxLines="1" + android:ellipsize="end" + android:layout_marginTop="6dp" + app:layout_constraintStart_toEndOf="@id/audioPlaybackControlButton" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + tools:text="Filename.mp3" /> + + <TextView + android:id="@+id/audioPlaybackDuration" + style="@style/Widget.Vector.TextView.Caption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginTop="2dp" + android:textColor="?vctr_content_tertiary" + app:layout_constraintStart_toStartOf="@id/messageFilenameView" + app:layout_constraintTop_toBottomOf="@id/messageFilenameView" + tools:text="0:23" /> + + <TextView + android:id="@+id/fileSize" + style="@style/Widget.Vector.TextView.Caption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="?vctr_content_tertiary" + android:layout_marginStart="4dp" + app:layout_constraintStart_toEndOf="@id/audioPlaybackDuration" + app:layout_constraintBottom_toBottomOf="@id/audioPlaybackDuration" + tools:text="(2MB)" /> + + <SeekBar + android:id="@+id/audioSeekBar" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginTop="12dp" + android:layout_marginBottom="10dp" + android:progressDrawable="@drawable/bg_seek_bar" + android:thumbTint="?vctr_content_tertiary" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toStartOf="@id/audioPlaybackTime" + app:layout_constraintTop_toBottomOf="@id/audioPlaybackControlButton" + app:layout_constraintBottom_toBottomOf="parent" + tools:progress="40" /> + + <TextView + android:id="@+id/audioPlaybackTime" + style="@style/Widget.Vector.TextView.Caption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="?vctr_content_tertiary" + android:layout_marginEnd="4dp" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="@id/audioSeekBar" + app:layout_constraintBottom_toBottomOf="@id/audioSeekBar" + tools:text="0:23" /> + + </androidx.constraintlayout.widget.ConstraintLayout> + + <include + android:id="@+id/messageFileUploadProgressLayout" + layout="@layout/media_upload_download_progress_layout" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginTop="8dp" + android:layout_marginEnd="32dp" + android:visibility="gone" + tools:visibility="visible" /> + +</LinearLayout> \ No newline at end of file diff --git a/vector/src/main/res/layout/item_timeline_event_live_location_start_stub.xml b/vector/src/main/res/layout/item_timeline_event_live_location_start_stub.xml new file mode 100644 index 0000000000..b81a6cc0e9 --- /dev/null +++ b/vector/src/main/res/layout/item_timeline_event_live_location_start_stub.xml @@ -0,0 +1,65 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <!-- Size will be overrode --> + <ImageView + android:id="@+id/locationLiveStartMap" + android:layout_width="300dp" + android:layout_height="200dp" + android:contentDescription="@string/a11y_static_map_image" + android:src="@drawable/bg_no_location_map" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" /> + + <ImageView + android:id="@+id/locationLiveStartBanner" + android:layout_width="0dp" + android:layout_height="48dp" + android:alpha="0.85" + android:src="?colorSurface" + app:layout_constraintBottom_toBottomOf="@id/locationLiveStartMap" + app:layout_constraintEnd_toEndOf="@id/locationLiveStartMap" + app:layout_constraintStart_toStartOf="@id/locationLiveStartMap" + tools:ignore="ContentDescription" /> + + <ImageView + android:id="@+id/locationLiveStartIcon" + android:layout_width="32dp" + android:layout_height="32dp" + android:layout_marginHorizontal="8dp" + android:background="@drawable/circle" + android:backgroundTint="?vctr_content_quaternary" + android:padding="3dp" + app:layout_constraintBottom_toBottomOf="@id/locationLiveStartBanner" + app:layout_constraintStart_toStartOf="@id/locationLiveStartBanner" + app:layout_constraintTop_toTopOf="@id/locationLiveStartBanner" + app:srcCompat="@drawable/ic_attachment_location_live_white" + tools:ignore="ContentDescription" /> + + <TextView + android:id="@+id/locationLiveStartTitle" + style="@style/Widget.Vector.TextView.Caption" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginHorizontal="8dp" + android:text="@string/location_share_live_started" + android:textColor="?vctr_content_tertiary" + app:layout_constraintBottom_toBottomOf="@id/locationLiveStartBanner" + app:layout_constraintStart_toEndOf="@id/locationLiveStartIcon" + app:layout_constraintTop_toTopOf="@id/locationLiveStartBanner" /> + + <ProgressBar + android:id="@+id/locationLiveStartLoader" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:indeterminateTint="?vctr_content_quaternary" + app:layout_constraintBottom_toTopOf="@id/locationLiveStartBanner" + app:layout_constraintEnd_toEndOf="@id/locationLiveStartMap" + app:layout_constraintStart_toStartOf="@id/locationLiveStartMap" + app:layout_constraintTop_toTopOf="@id/locationLiveStartMap" /> + +</androidx.constraintlayout.widget.ConstraintLayout> diff --git a/vector/src/main/res/layout/item_timeline_event_view_stubs_container.xml b/vector/src/main/res/layout/item_timeline_event_view_stubs_container.xml index 667db8fee2..355d5fa7fe 100644 --- a/vector/src/main/res/layout/item_timeline_event_view_stubs_container.xml +++ b/vector/src/main/res/layout/item_timeline_event_view_stubs_container.xml @@ -40,6 +40,13 @@ android:layout="@layout/item_timeline_event_voice_stub" tools:visibility="gone" /> + <ViewStub + android:id="@+id/messageContentAudioStub" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout="@layout/item_timeline_event_audio_stub" + tools:visibility="gone" /> + <ViewStub android:id="@+id/messageContentPollStub" android:layout_width="match_parent" @@ -52,6 +59,11 @@ android:layout_height="wrap_content" android:layout="@layout/item_timeline_event_location_stub" /> + <ViewStub + android:id="@+id/messageContentLiveLocationStartStub" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout="@layout/item_timeline_event_live_location_start_stub" /> </FrameLayout> diff --git a/vector/src/main/res/values-ar/strings.xml b/vector/src/main/res/values-ar/strings.xml index 10c10b8062..fe3abdcf80 100644 --- a/vector/src/main/res/values-ar/strings.xml +++ b/vector/src/main/res/values-ar/strings.xml @@ -872,4 +872,133 @@ <string name="message_view_reaction">اعرض الانفعالات</string> <string name="message_add_reaction">أضف انفعالًا</string> <string name="title_activity_emoji_reaction_picker">الانفعالات</string> + <string name="decide_who_can_find_and_join">اختر من يمكنهم العثور على الغرفة والانضمام إليها.</string> + <string name="tap_to_edit_spaces">اضغط لتعديل الفضاءات</string> + <string name="select_spaces">اختر الفضاءات</string> + <string name="room_create_member_of_space_name_can_join">أعضاء فضاء %s يمكنهم العثور على الغرفة ومعاينتها والانضمام إليها.</string> + <string name="room_settings_room_access_restricted_title">أعضاء الفضاء فقك</string> + <string name="room_settings_space_access_public_description">يمكن لأي كان العثور على الفضاء والانضمام إليه</string> + <string name="room_settings_room_access_public_description">يمكن لأي كان الانضمام للغرفة</string> + <string name="room_settings_room_access_public_title">علنيّة</string> + <string name="room_settings_room_access_private_invite_only_title">خاصة (عبر الدعوة فقط)</string> + <string name="room_settings_room_access_private_title">خاصة</string> + <string name="settings_show_join_leave_messages">أظهر حدثيْ الانضمام والمغادرة</string> + <string name="settings_send_typing_notifs_summary">أعلم المستخدمين أنك تكتب.</string> + <string name="settings_send_typing_notifs">أرسل إخطارات عند الكتابة</string> + <string name="settings_cryptography_manage_keys">إدارة مفاتيح التعميّة</string> + <string name="settings_integrations">تَكامُل</string> + <plurals name="seconds"> + <item quantity="zero">الآن</item> + <item quantity="one">ثانية واحدة</item> + <item quantity="two">ثانيتان</item> + <item quantity="few">%d ثوان</item> + <item quantity="many">%d ثانية</item> + <item quantity="other">%d ثانية</item> + </plurals> + <string name="login_server_url_form_other_hint">العنوان</string> + <string name="login_clear_homeserver_history">امسح التأريخ</string> + <string name="login_signin">لِج</string> + <string name="login_signup">سجّل</string> + <string name="login_signin_to">لج عبر %1$s</string> + <string name="login_connect_to_a_custom_server">اتص بخادم مخصص</string> + <string name="login_connect_to_modular">اتصل بخدمات مايتركس لـ Element</string> + <string name="login_connect_to">اتصل بـ %1$s</string> + <string name="login_continue">تابع</string> + <string name="login_social_signin_with">لِج عبر %s</string> + <string name="login_social_signup_with">سجل في %s</string> + <string name="login_social_continue_with">تابع بـ %s</string> + <string name="login_server_other_title">أخرى</string> + <string name="login_server_matrix_org_text">انضم لأكبر خادم علني مجانًا</string> + <string name="login_server_text">مثل البريد الالكتروني لن تحتاج سوى لحساب واحد للتواصل مع الجميع</string> + <string name="login_server_title">اختر خادمًا</string> + <string name="login_splash_already_have_account">لدي حساب سلفًا</string> + <string name="login_splash_create_account">أنشئ حسابًا</string> + <string name="login_splash_submit">ابدأ</string> + <string name="login_splash_text2">حافظ على خصوصية محادثاتك بالتعميّة</string> + <string name="login_splash_text1">تراسل مع أفراد أو مجموعات</string> + <string name="login_splash_title">تحكم في محادثاتك.</string> + <string name="ftue_personalize_skip_this_step">تخط هذه الخطوة</string> + <string name="ftue_personalize_submit">احفظ وتابع</string> + <string name="ftue_personalize_complete_subtitle">حُفظت تفضيلاتك.</string> + <string name="ftue_personalize_complete_title">كل شيئ جاهز!</string> + <string name="ftue_personalize_lets_go">لننطلق</string> + <string name="ftue_profile_picture_subtitle">يمكنك تغييرها في أي وقت.</string> + <string name="ftue_profile_picture_title">أضف صورة لللاحة</string> + <string name="ftue_display_name_entry_footer">يمكنك تغييره لاحقًا</string> + <string name="ftue_display_name_entry_title">الاسم العلني</string> + <string name="ftue_display_name_subtitle">سيظهر هذا الاسم مع رسائلك.</string> + <string name="ftue_display_name_title">اختر الاسم العلني</string> + <string name="ftue_account_created_subtitle">أُنشئ حسابك %s.</string> + <string name="ftue_account_created_congratulations_title">مبارك!</string> + <string name="ftue_account_created_take_me_home">انقلني للمنزل</string> + <string name="ftue_account_created_personalize">خصص لاحتك</string> + <string name="ftue_auth_use_case_connect_to_server">اتصل بخادم</string> + <string name="ftue_auth_use_case_join_existing_server">ترغب في الانضمام لخادم موجودٍ سلفًا؟</string> + <string name="ftue_auth_use_case_skip_partial">تخط هذا السؤال</string> + <string name="ftue_auth_use_case_option_three">مجتمعات</string> + <string name="ftue_auth_use_case_option_two">فِرق</string> + <string name="ftue_auth_use_case_option_one">الأصدقاء والعائلة</string> + <string name="ftue_auth_use_case_title">من أكثر من تحادثهم؟</string> + <string name="ftue_auth_carousel_encrypted_title">مراسلات آمنة.</string> + <string name="ftue_auth_carousel_control_title">أنت المتحكم.</string> + <string name="ftue_auth_carousel_secure_title">تحكم في محادثاتك.</string> + <string name="timeline_unread_messages">رسائل غير مقروءة</string> + <string name="room_join_rules_invite_by_you">جعلتَ الغرفة للمدعووين فقط.</string> + <string name="room_join_rules_invite">جعل %1$s الغرفة للمدعوين فقط.</string> + <string name="room_join_rules_public_by_you">جعلتَ الغرفة علنيّة لمن يملك رابطها.</string> + <string name="room_join_rules_public">جعل %1$s الغرفة علنيّة لمن يملك رابطها.</string> + <string name="help_long_click_on_room_for_more_options">اضغط مطولًا على الغرفة لتظهر مزيد من الخيارات</string> + <string name="no_ignored_users">لا تتجاهل أي مستخدم</string> + <string name="reaction_search_type_hint">اكتب كلمة مفتاحيّة لتعثر على تفاعل.</string> + <string name="notice_member_no_changes_by_you">لم تقم بأي تغيير</string> + <string name="notice_member_no_changes">لم يقم %1$s بأي تغيير</string> + <string name="room_list_quick_actions_room_settings">إعدادات الغرفة</string> + <string name="room_list_quick_actions_leave">غادر الغرفة</string> + <string name="room_list_quick_actions_favorite_remove">أزل من المفضلة</string> + <string name="room_list_quick_actions_favorite_add">أضف للمفضلة</string> + <string name="room_list_quick_actions_settings">الإعدادات</string> + <string name="room_list_quick_actions_notifications_mute">اكتم</string> + <string name="room_list_quick_actions_notifications_mentions">الذكر فقط</string> + <string name="room_list_quick_actions_notifications_all">كل الرسائل</string> + <string name="room_list_quick_actions_notifications_all_noisy">كل الرسائل (مزعج)</string> + <string name="message_ignore_user">تجاهل مستخدم</string> + <string name="login_social_continue">أَو</string> + <string name="room_alias_published_alias_main">هذا العنوان الرئيسي</string> + <string name="room_alias_published_alias_title">العناوين المنشورة</string> + <string name="space_settings_alias_title">عناوين الفضاء</string> + <string name="room_settings_alias_title">عناوين الغرفة</string> + <string name="room_settings_guest_access_title">اسمح للزوار الانضمام</string> + <string name="room_settings_space_access_title">النفاذ للفضاء</string> + <string name="room_settings_room_access_title">النفاذ للغرفة</string> + <string name="room_settings_access_rules_pref_dialog_title">من له النفاذ؟</string> + <string name="room_settings_room_notifications_account_settings">إعدادات الحساب</string> + <string name="room_settings_room_notifications_manage_notifications">يمكنك إدارة الإخطارات في %1$s.</string> + <string name="room_settings_room_notifications_notify_me">أخطرني بـ</string> + <string name="verify_new_session_was_not_me">لم أكن أنا</string> + <string name="verify_new_session_notice">استعمل هذه الجلسة لاستيثاق جلسة جديدة، مما يمنحها نفاذًا للرسائل المعماة.</string> + <string name="new_session">ولوج جديد، أنت من قمت به؟</string> + <string name="refresh">أنعش</string> + <string name="e2e_use_keybackup">فك قفل تأريخ الرسائل المعماة</string> + <string name="keys_backup_restore_success_title_already_up_to_date">المفاتيح محدثة سلفًا!</string> + <string name="encryption_settings_manage_message_recovery_summary">أدر النسخ الاحتياكي للمفاتيح</string> + <string name="encryption_message_recovery">استعادة الرسائل المعماة</string> + <string name="encryption_exported_successfully">نجح استيراد المفاتيح</string> + <string name="room_settings_enable_encryption_dialog_title">أتريد تفعيل التعميّة؟</string> + <string name="room_settings_enable_encryption_no_permission">ليس لديك إذن لتفعيل التعميّة في هذه الغرفة.</string> + <string name="settings_category_composer">محرر الرسائل</string> + <string name="command_description_rainbow">يرسل الرسالة المعطاة ملونة بألوان قوس قزح</string> + <string name="rendering_event_error_exception">${app_name} واجه مشكلة في تصيير الحدث ذو المعرف \'%1$s\'</string> + <string name="rendering_event_error_type_of_event_not_handled">${app_name} لا يستطيع التعامل مع ملفات من نوع \'%1$s\'</string> + <string name="room_member_open_or_create_dm">رسالة مباشرة</string> + <string name="room_member_power_level_moderator_in">مشرف لـ %1$s</string> + <string name="room_member_power_level_admin_in">مدير لـ %1$s</string> + <string name="room_member_power_level_users">المستخدمون</string> + <string name="room_member_power_level_invites">الدعوات</string> + <string name="room_member_power_level_custom">مخصص</string> + <string name="room_member_power_level_moderators">المشرفون</string> + <string name="room_member_power_level_admins">المديرون</string> + <string name="room_profile_leaving_room">يغادر الغرفة.…</string> + <string name="direct_room_profile_section_more_leave">غادر</string> + <string name="room_profile_section_more_leave">غادر الغرفة</string> + <string name="room_profile_section_more_uploads">المرفوعات</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-cs/strings.xml b/vector/src/main/res/values-cs/strings.xml index c66ff56b3e..3121f859f3 100644 --- a/vector/src/main/res/values-cs/strings.xml +++ b/vector/src/main/res/values-cs/strings.xml @@ -2485,4 +2485,23 @@ \n \nPůjde o jednorázový přechod, protože vlákna jsou nyní součástí Matrix specifikace.</string> <string name="threads_notice_migration_title">Vlákna se blíží k betaverzi 🎉</string> + <string name="live_location_sharing_notification_description">Probíhá sdílení polohy</string> + <string name="live_location_sharing_notification_title">${app_name} poloha živě</string> + <string name="error_forbidden_digits_only_username">Domovský server neakceptuje uživatelská jména obsahující pouze číslice.</string> + <string name="ftue_personalize_skip_this_step">Přeskočit tento krok</string> + <string name="ftue_personalize_submit">Uložit a pokračovat</string> + <string name="ftue_personalize_complete_subtitle">Vaše předvolby byly uloženy.</string> + <string name="ftue_personalize_complete_title">Vše je připraveno!</string> + <string name="ftue_personalize_lets_go">Jdeme na to</string> + <string name="ftue_profile_picture_subtitle">Tuto můžete kdykoli změnit.</string> + <string name="ftue_profile_picture_title">Přidat profilový obrázek</string> + <string name="ftue_display_name_entry_footer">Později to můžete změnit</string> + <string name="ftue_display_name_entry_title">Zobrazované jméno</string> + <string name="ftue_display_name_subtitle">Toto se zobrazí při odesílání zpráv.</string> + <string name="ftue_display_name_title">Zvolte si zobrazované jméno</string> + <string name="ftue_account_created_subtitle">Váš účet %s byl založen.</string> + <string name="ftue_account_created_congratulations_title">Gratulujeme!</string> + <string name="ftue_account_created_take_me_home">Vezmi mě domů</string> + <string name="ftue_account_created_personalize">Přizpůsobit profil</string> + <string name="action_disable">Zakázat</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-de/strings.xml b/vector/src/main/res/values-de/strings.xml index 866f05b3a6..d463276bb1 100644 --- a/vector/src/main/res/values-de/strings.xml +++ b/vector/src/main/res/values-de/strings.xml @@ -2428,4 +2428,5 @@ <string name="a11y_location_share_option_user_live_icon">Live-Standort teilen</string> <string name="location_share_option_user_live">Live-Standort teilen</string> <string name="threads_notice_migration_title">Threads nähern sich der Beta 🎉</string> + <string name="action_disable">Deaktivieren</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-et/strings.xml b/vector/src/main/res/values-et/strings.xml index e320550323..19b4d37102 100644 --- a/vector/src/main/res/values-et/strings.xml +++ b/vector/src/main/res/values-et/strings.xml @@ -245,7 +245,7 @@ <string name="are_you_sure">Kas sa oled kindel\?</string> <string name="backup">Varunda</string> <string name="sign_out_bottom_sheet_will_lose_secure_messages">Kui sa enne väljalogimist ei varunda oma võtmeid, siis sa kaotad ligipääsu oma krüptitud sõnumitele.</string> - <string name="loading">Laeme…</string> + <string name="loading">Laadime…</string> <string name="ok">Sobib</string> <string name="action_cancel">Tühista</string> <string name="action_save">Salvesta</string> @@ -1958,7 +1958,7 @@ <string name="spaces_beta_welcome_to_spaces_desc">Kogukonnakeskused on uus võimalus siduda jututubasid ja inimesi.</string> <string name="space_add_existing_rooms">Lisa olemasolevaid jututubasid ja kogukonnakeskuseid</string> <string name="leave_space">Lahku kogukonnast</string> - <string name="space_add_child_title">Lisa jututuba</string> + <string name="space_add_child_title">Lisa jututube</string> <string name="space_explore_activity_title">Tutvu jututubadega</string> <plurals name="space_people_you_know"> <item quantity="one">%d sinu tuttav on juba liitunud</item> @@ -1968,7 +1968,7 @@ \nProovi hiljem uuesti või küsi jututoa haldajalt, kas sul on olemas selleks vajalikud õigused.</string> <string name="join_anyway">Liitu ikkagi</string> <string name="join_space">Liitu kogukonnakeskusega</string> - <string name="create_space">Loo kogukonnakeskus</string> + <string name="create_space">Loo kogukond</string> <string name="skip_for_now">Hetkel jäta vahele</string> <string name="share_space_link_message">Palun liitu %1$s kogukonnakeskusega %2$s</string> <string name="invite_just_to_this_room_desc">Nad ei saa osalema %s jututoas</string> @@ -2007,7 +2007,7 @@ <string name="create_spaces_choose_type_label">Missugust kogukonnakeskust sooviksid sa luua\?</string> <string name="your_private_space">Sinu privaatne kogukonnakeskus</string> <string name="your_public_space">Sinu avalik kogukonnakeskus</string> - <string name="add_space">Lisa kogukonnakeskus</string> + <string name="add_space">Lisa kogukond</string> <string name="command_description_leave_room">Lahku antud tunnusega jututoast (tunnuse puudumisel jututoast, kus hetkel asud)</string> <string name="command_description_join_space">Liitu kogukonnakeskusega tema tunnuse alusel</string> <string name="command_description_create_space">Loo kogukonnakeskus</string> @@ -2438,4 +2438,23 @@ \n \nKuna jutulõngad on nüüd osa Matrix\'i spetsifikatsioonist, siis see on ühekordne muudatus.</string> <string name="threads_notice_migration_title">Jutulõngad on peaaegu valmis 🎉</string> + <string name="live_location_sharing_notification_description">Asukoha reaalajas jagamine on hetkel kasutusel</string> + <string name="live_location_sharing_notification_title">Asukoht reaalajas - ${app_name}</string> + <string name="error_forbidden_digits_only_username">Koduserver ei võimalda ainult numbritest koosneva kasutajanime loomist.</string> + <string name="ftue_personalize_skip_this_step">Jäta see samm vahele</string> + <string name="ftue_personalize_submit">Salvesta ja jätka</string> + <string name="ftue_personalize_complete_subtitle">Sinu eelistused on salvestatud.</string> + <string name="ftue_personalize_complete_title">Kõik on valmis!</string> + <string name="ftue_personalize_lets_go">Alustame nüüd</string> + <string name="ftue_profile_picture_subtitle">Sa võid seda hiljem alati muuta.</string> + <string name="ftue_profile_picture_title">Lisa profiilipilt</string> + <string name="ftue_display_name_entry_footer">Sa võid seda hiljem muuta</string> + <string name="ftue_display_name_entry_title">Kuvatav nimi</string> + <string name="ftue_display_name_subtitle">Seda näidatakse sõnumite saatmisel.</string> + <string name="ftue_display_name_title">Vali kuvatav nimi</string> + <string name="ftue_account_created_subtitle">Sinu kasutajakonto %s on nüüd olemas.</string> + <string name="ftue_account_created_congratulations_title">Õnnitlused!</string> + <string name="ftue_account_created_take_me_home">Mine avalehele</string> + <string name="ftue_account_created_personalize">Isikupärasta oma profiili</string> + <string name="action_disable">Lülita välja</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-fa/strings.xml b/vector/src/main/res/values-fa/strings.xml index ab6bac5c1b..9a23913f76 100644 --- a/vector/src/main/res/values-fa/strings.xml +++ b/vector/src/main/res/values-fa/strings.xml @@ -1247,7 +1247,7 @@ <string name="search_no_results">نتیجهای در پی نداشت</string> <string name="search_banned_user_hint">فیلترکردن کاربران مسدود شده</string> <plurals name="room_details_selected"> - <item quantity="one">%d مورد</item> + <item quantity="one">۱ مورد</item> <item quantity="other">%d مورد</item> </plurals> <string name="ssl_only_accept">تنها اگر مدیر کارساز، اثرانگشتی منتشر کرده که با بالایی مطابق است، بپذیرید.</string> @@ -2430,4 +2430,31 @@ <string name="location_share_option_user_current">همرسانی مکان کنونیم</string> <string name="a11y_location_share_locate_button">بزرگنمایی به مکان کنونی</string> <string name="a11y_location_share_pin_on_map">سنجاق مکان گزیده روی نقشه</string> + <string name="threads_notice_migration_message">داریم به ارائه یک بتای عمومی برای رشتهها نزدیکتر میشویم. +\n +\nهمینطور که برایش آماده میشویم، نیاز به انجام چند تغییر است: رشتههایی که پیش از این ایجاد شدهاند،به شکل پاسخهای عادی نشان داده خواهند شد. +\n +\nاین کار، یک تبدیل یک باره است؛ چرا که رشتهها اکنون بخشی از مشخّصات ماتریکسند.</string> + <string name="threads_notice_migration_title">رشتهها به بتا می رسند 🎉</string> + <string name="live_location_sharing_notification_description">همرساین مکان در حال انجام است</string> + <string name="live_location_sharing_notification_title">مکان زندهٔ ${app_name}</string> + <string name="location_in_background_missing_permission_dialog_content">اگر میخواهید مکانتان را همرسانی کنید، ${app_name} نیاز به دسترسی همیشگی مکان هنگام در پسزمینه بودن کاره دارد. +\nفقط برای مدتی که برمیگزینید، به مکانتان دسترسی خواهیم داشت.</string> + <string name="error_forbidden_digits_only_username">کارساز خانگی، نامهای کاربری فقط رقمی را نمیپذیرد.</string> + <string name="ftue_personalize_skip_this_step">پرش از این گام</string> + <string name="ftue_personalize_submit">ذخیره و ادامه</string> + <string name="ftue_personalize_complete_subtitle">ترجیحاتتان ذخیره شد.</string> + <string name="ftue_personalize_complete_title">همهچیز تنظیم شده!</string> + <string name="ftue_personalize_lets_go">بزن بریم</string> + <string name="ftue_profile_picture_subtitle">میتوانید هرزمانی تغییرش دهید.</string> + <string name="ftue_display_name_title">گزینش نامی نمایشی</string> + <string name="ftue_profile_picture_title">افزودن یک تصویر نمایه</string> + <string name="ftue_display_name_entry_footer">میتوانید بعدها تغییرش دهید</string> + <string name="ftue_display_name_entry_title">نام نمایشی</string> + <string name="ftue_display_name_subtitle">هنگامی که پیام میفرستید نشان داده خواهد شد.</string> + <string name="ftue_account_created_subtitle">حسابتان %s ایجاد شد.</string> + <string name="ftue_account_created_congratulations_title">تبریک!</string> + <string name="ftue_account_created_take_me_home">مرا به خانه ببر</string> + <string name="ftue_account_created_personalize">شخصی سازی نمایه</string> + <string name="action_disable">از کار انداختن</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-fi/strings.xml b/vector/src/main/res/values-fi/strings.xml index c5e67771dd..9d084fa8ba 100644 --- a/vector/src/main/res/values-fi/strings.xml +++ b/vector/src/main/res/values-fi/strings.xml @@ -42,7 +42,7 @@ <string name="initial_sync_start_importing_account">Alkusynkronointi: \nTuodaan tiliä…</string> <string name="initial_sync_start_importing_account_crypto">Alkusynkronointi: -\nTuodaan kryptoa</string> +\nTuodaan krypto</string> <string name="initial_sync_start_importing_account_rooms">Alkusynkronointi: \nTuodaan huoneita</string> <string name="initial_sync_start_importing_account_joined_rooms">Alkusynkronointi: @@ -267,7 +267,7 @@ <string name="action_remove">Poista</string> <string name="action_join">Liity</string> <string name="action_reject">Hylkää</string> - <string name="room_jump_to_first_unread">Siirry ensimmäiseen lukemattomaan viestiin.</string> + <string name="room_jump_to_first_unread">Siirry lukemattomaan</string> <string name="room_participants_leave_prompt_title">Poistu huoneesta</string> <string name="room_participants_leave_prompt_msg">Haluatko varmasti poistua huoneesta?</string> <string name="room_participants_header_direct_chats">YKSITYISKESKUSTELUT</string> @@ -516,7 +516,7 @@ <string name="settings_call_ringtone_use_app_ringtone">Käytä ${app_name}in oletussoittoääntä saapuville puheluille</string> <string name="settings_call_ringtone_title">Saapuvien puheluiden soittoääni</string> <string name="video_call_in_progress">Videopuhelu menossa…</string> - <string name="list_members">Käyttäjälista</string> + <string name="list_members">Jäsenet</string> <plurals name="room_title_members"> <item quantity="one">yksi jäsen</item> <item quantity="other">%d jäsentä</item> @@ -1562,7 +1562,7 @@ <string name="space_leave_prompt_msg_private">Et voi liittyä uudelleen, ellei sinua kutsuta uudelleen.</string> <string name="space_leave_prompt_msg_only_you">Olet ainoa henkilö täällä. Jos poistut, kukaan ei voi liittyä tänne tulevaisuudessa, et edes sinä.</string> <string name="space_leave_prompt_msg_with_name">Haluatko varmasti poistua avaruudesta %s\?</string> - <string name="leave_space">Poistu avaruudesta</string> + <string name="leave_space">Poistu</string> <string name="space_add_child_title">Lisää huoneita</string> <string name="space_explore_activity_title">Selaa huoneita</string> <plurals name="space_people_you_know"> @@ -2053,4 +2053,54 @@ <item quantity="other">%1$s lisäsi tälle huoneelle vaihtoehtoiset osoitteet %2$s.</item> </plurals> <string name="room_error_access_unauthorized">Sinulla ei ole lupaa liittyä tähän huoneeseen</string> + <string name="room_message_autocomplete_users">Käyttäjät</string> + <plurals name="message_reaction_show_more"> + <item quantity="one">%1$d lisää</item> + <item quantity="other">%1$d lisää</item> + </plurals> + <string name="tooltip_attachment_file">Lähetä tiedosto</string> + <string name="location_share_live_stop">Pysäytä</string> + <string name="a11y_location_share_option_pinned_icon">Jaa tämä sijainti</string> + <string name="location_share_option_pinned">Jaa tämä sijainti</string> + <string name="a11y_location_share_option_user_current_icon">Jaa nykyinen sijaintini</string> + <string name="location_share_option_user_current">Jaa nykyinen sijaintini</string> + <string name="restart_the_application_to_apply_changes">Käynnistä sovellus uudelleen, jotta muutos tulee voimaan.</string> + <string name="space_add_existing_rooms">Lisää olemassa olevia huoneita ja avaruuksia</string> + <string name="dont_leave_any">Älä poistu mistään huoneesta ja avaruudesta</string> + <string name="leave_all_rooms_and_spaces">Poistu kaikista huoneista ja avaruuksista</string> + <string name="use_latest_app">Käytä ${app_name}in uusinta versiota muilla laitteillasi:</string> + <string name="ftue_personalize_skip_this_step">Ohita tämä vaihe</string> + <string name="ftue_personalize_submit">Tallenna ja jatka</string> + <string name="ftue_personalize_complete_subtitle">Asetukset on tallennettu.</string> + <string name="ftue_personalize_complete_title">Kaikki valmista!</string> + <string name="ftue_personalize_lets_go">Menoksi</string> + <string name="ftue_profile_picture_subtitle">Voit vaihtaa tämän milloin tahansa.</string> + <string name="ftue_profile_picture_title">Lisää profiilikuva</string> + <string name="ftue_display_name_entry_footer">Voit vaihtaa tämän myöhemmin</string> + <string name="ftue_display_name_entry_title">Näyttönimi</string> + <string name="ftue_display_name_subtitle">Tämä näytetään, kun lähetät viestejä.</string> + <string name="ftue_display_name_title">Valitse näyttönimi</string> + <string name="ftue_account_created_subtitle">Tilisi %s on luotu.</string> + <string name="ftue_account_created_congratulations_title">Onnittelut!</string> + <string name="ftue_account_created_personalize">Personoi profiili</string> + <string name="ftue_auth_use_case_skip_partial">ohittaa tämän kysymyksen</string> + <string name="ftue_auth_use_case_skip">Ei varmuutta vielä\? Voit %s</string> + <string name="settings_discovery_no_policy_provided">Identiteettipalvelin ei tarjoa käytäntöä</string> + <string name="settings_discovery_hide_identity_server_policy_title">Piilota identiteettipalvelimen käytäntö</string> + <string name="settings_discovery_show_identity_server_policy_title">Näytä identiteettipalvelimen käytäntö</string> + <string name="error_jitsi_join_conf">Valitettavasti konfrenssiin liityttäessä ilmeni virhe</string> + <string name="legals_no_policy_provided">Tämä palvelin ei tarjoa mitään käytäntöä.</string> + <string name="legals_identity_server_title">Identiteettipalvelimesi käytäntö</string> + <string name="legals_home_server_title">Kotipalvelimesi käytäntö</string> + <string name="legals_application_title">${app_name}-käytäntö</string> + <string name="action_thread_copy_link_to_thread">Kopioi linkki ketjuun</string> + <string name="action_disable">Poista käytöstä</string> + <string name="preference_system_settings">Järjestelmän asetukset</string> + <string name="preference_help_summary">Apua ${app_name}in käyttöön</string> + <string name="preference_root_legals">Lainopilliset asiat</string> + <string name="analytics_opt_in_content_link">tästä</string> + <string name="analytics_opt_in_content">Auta meitä tunnistamaan mahdollisia ongelmia ja parantamaan ${app_name}iä jakamalla anonyymia käyttödataa. Ymmärtääksemme miten ihmiset käyttävät useita laitteita, luomme satunnaisen tunnisteen, joka jaetaan kaikkien laitteidesi kesken. +\n +\nLue käyttöehdot %s.</string> + <string name="analytics_opt_in_title">Auta parantamaan ${app_name}iä</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-fr/strings.xml b/vector/src/main/res/values-fr/strings.xml index c9230ec49e..ce69d574ba 100644 --- a/vector/src/main/res/values-fr/strings.xml +++ b/vector/src/main/res/values-fr/strings.xml @@ -501,7 +501,7 @@ <item quantity="one">%d nouveau message</item> <item quantity="other">%d nouveaux messages</item> </plurals> - <string name="list_members">Liste les membres</string> + <string name="list_members">Membres</string> <plurals name="notification_unread_notified_messages"> <item quantity="one">%d message notifié non lu</item> <item quantity="other">%d messages notifiés non lus</item> @@ -1978,7 +1978,7 @@ <string name="you_are_invited">Vous êtes invité</string> <string name="spaces_beta_welcome_to_spaces_desc">Les espaces sont une nouvelle manière de regrouper les salons et les gens.</string> <string name="space_add_existing_rooms">Ajouter des salons et espaces existants</string> - <string name="leave_space">Quitter l’espace</string> + <string name="leave_space">Quitter</string> <string name="space_add_child_title">Ajouter des salons</string> <string name="space_explore_activity_title">Parcourir les salons</string> <plurals name="space_people_you_know"> @@ -2419,4 +2419,42 @@ <item quantity="one">%d changement des ACL du serveur</item> <item quantity="other">%d changements des ACL du serveur</item> </plurals> + <string name="live_location_sharing_notification_description">Partage de la position en cours</string> + <string name="live_location_sharing_notification_title">Position en temps réel de ${app_name}</string> + <string name="location_share_live_stop">Arrêter</string> + <string name="location_share_live_enabled">Position en temps réel activée</string> + <string name="location_in_background_missing_permission_dialog_content">Si vous souhaitez partager votre position en temps réel, ${app_name} a besoin de l’autorisation d’accès permanent à la position quand l’application est en arrière-plan. +\nNous accèderons à votre position seulement pendant la durée que vous définissez.</string> + <string name="location_in_background_missing_permission_dialog_title">Autoriser l’accès</string> + <string name="a11y_location_share_option_pinned_icon">Partager cet emplacement</string> + <string name="location_share_option_pinned">Partager cet emplacement</string> + <string name="a11y_location_share_option_user_live_icon">Partager la position en temps réel</string> + <string name="location_share_option_user_live">Partager la position en temps réel</string> + <string name="a11y_location_share_option_user_current_icon">Partager ma position actuelle</string> + <string name="location_share_option_user_current">Partager ma position actuelle</string> + <string name="a11y_location_share_locate_button">Agrandir jusqu’à l’emplacement actuel</string> + <string name="a11y_location_share_pin_on_map">Épingle de l’emplacement sélectionné sur la carte</string> + <string name="error_forbidden_digits_only_username">Le serveur hôte n’accepte pas de nom d’utilisateur avec seulement des chiffres.</string> + <string name="ftue_personalize_skip_this_step">Ignorer cette étape</string> + <string name="ftue_personalize_submit">Enregistrer et continuer</string> + <string name="ftue_personalize_complete_subtitle">Vos préférences ont été enregistrées.</string> + <string name="ftue_personalize_complete_title">Tout est prêt !</string> + <string name="ftue_personalize_lets_go">Allons-y</string> + <string name="ftue_profile_picture_subtitle">Vous pouvez la changer à tout moment.</string> + <string name="ftue_profile_picture_title">Ajouter une photo de profil</string> + <string name="ftue_display_name_entry_footer">Vous pourrez le changer plus tard</string> + <string name="ftue_display_name_entry_title">Nom d’affichage</string> + <string name="ftue_display_name_subtitle">Il sera affiché quand vous enverrez des messages.</string> + <string name="ftue_display_name_title">Choisissez un nom d’affichage</string> + <string name="ftue_account_created_subtitle">Votre compte %s a été créé.</string> + <string name="ftue_account_created_congratulations_title">Félicitations !</string> + <string name="ftue_account_created_take_me_home">Aller à l’accueil</string> + <string name="ftue_account_created_personalize">Personnaliser le profil</string> + <string name="threads_notice_migration_title">Les fils de discussion se rapproche de la bêta 🎉</string> + <string name="action_disable">Désactiver</string> + <string name="threads_notice_migration_message">Nous nous approchons d’une publication en bêta des fils de discussions. +\n +\nPour nous y préparer, nous avons besoin de faire certains changements : les fils créés avant maintenant seront affichés comme des réponses classiques. +\n +\nCette transition sera unique, maintenant que les fils de discussions ont intégré la spécification de Matrix.</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-hu/strings.xml b/vector/src/main/res/values-hu/strings.xml index f13a97d216..33bde2944e 100644 --- a/vector/src/main/res/values-hu/strings.xml +++ b/vector/src/main/res/values-hu/strings.xml @@ -2438,4 +2438,23 @@ A Visszaállítási Kulcsot tartsd biztonságos helyen, mint pl. egy jelszókeze <string name="a11y_location_share_locate_button">Ugrás a jelenlegi pozícióra</string> <string name="a11y_location_share_pin_on_map">Kiválasztott hely rögzítése a térképen</string> <string name="threads_notice_migration_title">Üzenetszálak lassan béta állapotba kerülnek 🎉</string> + <string name="live_location_sharing_notification_description">Helymeghatározás folyamatban</string> + <string name="live_location_sharing_notification_title">${app_name} Folyamatos helymeghatározás</string> + <string name="error_forbidden_digits_only_username">A matrix szerver nem fogad el olyan felhasználói nevet ami csak számokból áll.</string> + <string name="ftue_personalize_skip_this_step">Lépés kihagyása</string> + <string name="ftue_personalize_submit">Mentés és tovább</string> + <string name="ftue_personalize_complete_subtitle">A beállítások elmentve.</string> + <string name="ftue_personalize_complete_title">Minden kész!</string> + <string name="ftue_personalize_lets_go">Gyerünk</string> + <string name="ftue_profile_picture_subtitle">Bármikor megváltoztatható.</string> + <string name="ftue_profile_picture_title">Profilkép hozzáadása</string> + <string name="ftue_display_name_entry_footer">Ezt később meg lehet változtatni</string> + <string name="ftue_display_name_entry_title">Megjelenítendő név</string> + <string name="ftue_display_name_subtitle">Ez fog megjelenni amikor üzenetet küldesz.</string> + <string name="ftue_display_name_title">Válassz egy megjelenítési nevet</string> + <string name="ftue_account_created_subtitle">A fiókod elkészült: %s.</string> + <string name="ftue_account_created_congratulations_title">Gratulálunk!</string> + <string name="ftue_account_created_take_me_home">Vigyél haza</string> + <string name="ftue_account_created_personalize">Profil személyre szabása</string> + <string name="action_disable">Tiltás</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-in/strings.xml b/vector/src/main/res/values-in/strings.xml index 29831c1377..5ca1a361d4 100644 --- a/vector/src/main/res/values-in/strings.xml +++ b/vector/src/main/res/values-in/strings.xml @@ -1742,7 +1742,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan.</string> \nCoba lagi nanti, atau tanyakan ke admin ruangan untuk mengecek jika Anda punya akses.</string> <string name="join_anyway">Bergabung Saja</string> <string name="join_space">Bergabung ke Space</string> - <string name="create_space">Buat Space</string> + <string name="create_space">Buat space</string> <string name="skip_for_now">Lewat untuk sekarang</string> <string name="share_space_link_message">Bergabung ke space saya %1$s %2$s</string> <string name="invite_just_to_this_room_desc">Mereka tidak akan menjadi bagian dari %s</string> @@ -1784,7 +1784,7 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan.</string> <string name="create_spaces_choose_type_label">Tipe space apa yang Anda ingin buat\?</string> <string name="your_private_space">Space privat Anda</string> <string name="your_public_space">Space publik Anda</string> - <string name="add_space">Tambahkan Space</string> + <string name="add_space">Tambahkan space</string> <string name="private_space">Space privat</string> <string name="public_space">Space publik</string> <string name="event_status_delete_all_failed_dialog_message">Apakah Anda yakin untuk menghapus semua pesan yang belum dikirim di ruangan ini\?</string> @@ -2393,4 +2393,23 @@ Di masa mendatang proses verifikasi ini akan dimutakhirkan.</string> \n \nIni hanya transisi sekali, utasan sekarang sebagai bagian dari spesifikasi Matrix.</string> <string name="threads_notice_migration_title">Utasan Mencapai Beta 🎉</string> + <string name="live_location_sharing_notification_description">Penbagian lokasi sedang dilakukan</string> + <string name="live_location_sharing_notification_title">${app_name} Lokasi langsung</string> + <string name="error_forbidden_digits_only_username">Homeserver tidak menerima nama pengguna dengan hanya angka.</string> + <string name="ftue_personalize_skip_this_step">Lewati</string> + <string name="ftue_personalize_submit">Simpan dan lanjutkan</string> + <string name="ftue_personalize_complete_subtitle">Preferensi Anda telah disimpan.</string> + <string name="ftue_personalize_complete_title">Anda siap!</string> + <string name="ftue_personalize_lets_go">Ayo</string> + <string name="ftue_profile_picture_subtitle">Anda dapat mengubahnya kapan saja.</string> + <string name="ftue_profile_picture_title">Tambahkan sebuah foto profil</string> + <string name="ftue_display_name_entry_footer">Anda dapat mengubahnya nanti</string> + <string name="ftue_display_name_entry_title">Nama Tampilan</string> + <string name="ftue_display_name_subtitle">Ini akan ditampilkan ketika Anda mengirim pesan.</string> + <string name="ftue_display_name_title">Pilih nama tampilan</string> + <string name="ftue_account_created_subtitle">Akun %s Anda telah dibuat.</string> + <string name="ftue_account_created_congratulations_title">Selamat!</string> + <string name="ftue_account_created_take_me_home">Kembalikan saya ke beranda</string> + <string name="ftue_account_created_personalize">Ubah profil</string> + <string name="action_disable">Nonaktifkan</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-it/strings.xml b/vector/src/main/res/values-it/strings.xml index d14aa3c671..15f08ba6da 100644 --- a/vector/src/main/res/values-it/strings.xml +++ b/vector/src/main/res/values-it/strings.xml @@ -1959,7 +1959,7 @@ \nRiprova più tardi, o chiedi a un amministratore della stanza di controllare se hai l\'accesso.</string> <string name="join_anyway">Unisciti comunque</string> <string name="join_space">Unisciti a uno Spazio</string> - <string name="create_space">Crea Spazio</string> + <string name="create_space">Crea spazio</string> <string name="skip_for_now">Per il momento, salta</string> <string name="share_space_link_message">Unisciti al mio Spazio %1$s %2$s</string> <string name="invite_just_to_this_room_desc">Non faranno parte di %s</string> @@ -1998,7 +1998,7 @@ <string name="create_spaces_choose_type_label">Che tipo di Spazio vuoi creare\?</string> <string name="your_private_space">Il tuo Spazio privato</string> <string name="your_public_space">Il tuo Spazio pubblico</string> - <string name="add_space">Aggiungi Spazio</string> + <string name="add_space">Aggiungi spazio</string> <string name="command_description_leave_room">Esci dalla stanza con un ID (o dalla stanza attuale se vuota)</string> <string name="command_description_join_space">Unisciti allo Spazio con un ID</string> <string name="command_description_create_space">Crea uno Spazio</string> @@ -2429,4 +2429,23 @@ \n \nSarà una transizione una-tantum, dato che le conversazioni ora sono parte delle specifiche di Matrix.</string> <string name="threads_notice_migration_title">I messaggi in conversazioni entrano in beta 🎉</string> + <string name="ftue_account_created_take_me_home">Portami a casa</string> + <string name="live_location_sharing_notification_description">Stai condividendo la posizione</string> + <string name="live_location_sharing_notification_title">Posizione in tempo reale di ${app_name}</string> + <string name="error_forbidden_digits_only_username">L\'homeserver non accetta nomi utente con solo numeri.</string> + <string name="ftue_personalize_skip_this_step">Salta questo passo</string> + <string name="ftue_personalize_submit">Salva e continua</string> + <string name="ftue_personalize_complete_subtitle">Le tue preferenze sono state salvate.</string> + <string name="ftue_personalize_complete_title">Tutto pronto!</string> + <string name="ftue_personalize_lets_go">Andiamo</string> + <string name="ftue_profile_picture_subtitle">Puoi cambiarla in qualsiasi momento.</string> + <string name="ftue_profile_picture_title">Aggiungi un\'immagine del profilo</string> + <string name="ftue_display_name_entry_footer">Puoi cambiarlo in seguito</string> + <string name="ftue_display_name_entry_title">Nome da mostrare</string> + <string name="ftue_display_name_subtitle">Verrà mostrato quando invii messaggi.</string> + <string name="ftue_display_name_title">Scegli un nome da mostrare</string> + <string name="ftue_account_created_subtitle">Il tuo account %s è stato creato.</string> + <string name="ftue_account_created_congratulations_title">Congratulazioni!</string> + <string name="ftue_account_created_personalize">Personalizza profilo</string> + <string name="action_disable">Disattiva</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-iw/strings.xml b/vector/src/main/res/values-iw/strings.xml index 2e1f521ff1..d4eb42a095 100644 --- a/vector/src/main/res/values-iw/strings.xml +++ b/vector/src/main/res/values-iw/strings.xml @@ -1952,8 +1952,8 @@ </plurals> <plurals name="missed_audio_call"> <item quantity="one">שיחה שלא נענתה</item> - <item quantity="two">"%d שיחות שלא נענו"</item> - <item quantity="many">"%d שיחות שלא נענו"</item> + <item quantity="two">%d שיחות שלא נענו</item> + <item quantity="many">%d שיחות שלא נענו</item> <item quantity="other">שיחה שלא נענתה</item> </plurals> <string name="call_ringing">צלצול שיחה…</string> @@ -2099,8 +2099,8 @@ <plurals name="call_active_status"> <item quantity="one">שיחה פעילה ·</item> <item quantity="two">%1$d שיחות פעילות ·</item> - <item quantity="many"/> - <item quantity="other"/> + <item quantity="many">%1$d שיחות פעילות ·</item> + <item quantity="other">%1$d שיחות פעילות ·</item> </plurals> <string name="call_only_active">שיחה פעילה (%1$s)</string> <string name="call_dial_pad_lookup_error">אירעה שגיאה בחיפוש מספר הטלפון</string> @@ -2132,9 +2132,9 @@ <string name="room_notification_two_users_are_typing">%1$s ו %2$s</string> <plurals name="notice_room_server_acl_changes"> <item quantity="one">%d שינוי ברשימות ACL בשרתים</item> - <item quantity="two"/> - <item quantity="many"/> - <item quantity="other"/> + <item quantity="two">%d שינוים ברשימות ACL בשרתים</item> + <item quantity="many">%d שינוים ברשימות ACL בשרתים</item> + <item quantity="other">%d שינוים ברשימות ACL בשרתים</item> </plurals> <string name="space_settings_manage_rooms">נהל חדרים</string> <string name="decide_who_can_find_and_join">החלט מי יכול לראות ולהצטרף לחדר זה.</string> diff --git a/vector/src/main/res/values-ja/strings.xml b/vector/src/main/res/values-ja/strings.xml index e87e5653ca..672e2472bb 100644 --- a/vector/src/main/res/values-ja/strings.xml +++ b/vector/src/main/res/values-ja/strings.xml @@ -355,7 +355,7 @@ <plurals name="membership_changes"> <item quantity="other">%d個のメンバーシップの変更</item> </plurals> - <string name="list_members">メンバーを表示</string> + <string name="list_members">メンバー</string> <plurals name="room_title_members"> <item quantity="other">%d名のメンバー</item> </plurals> @@ -1520,7 +1520,7 @@ <string name="delete_poll_dialog_title">アンケートを削除</string> <string name="create_space">スペースを作成</string> <string name="join_space">スペースに参加</string> - <string name="leave_space">スペースを退出</string> + <string name="leave_space">退出</string> <string name="space_settings_manage_rooms">ルームを管理</string> <string name="this_space_has_no_rooms">このスペースにはルームがありません</string> <string name="error_voice_message_unable_to_play">音声メッセージを再生できません</string> @@ -2342,4 +2342,34 @@ <string name="set_a_security_phrase_notice">あなたしか知らないセキュリティーフレーズを入力してください。サーバーで機密情報を保護するために使用します。</string> <string name="message_reaction_show_less">詳細を非表示</string> <string name="invite_people_to_your_space_desc">他の参加者はいません。%sに招待しましょう。</string> + <string name="location_share_live_enabled">位置情報(ライブ)が有効です</string> + <string name="location_in_background_missing_permission_dialog_title">アクセスを許可</string> + <string name="a11y_location_share_option_user_current_icon">現在の位置情報を共有</string> + <string name="location_share_option_user_current">現在の位置情報を共有</string> + <string name="create_spaces_room_public_header_desc">ルームを作成します。後から追加できます。</string> + <plurals name="entries"> + <item quantity="other">%d個のエントリー</item> + </plurals> + <string name="ftue_personalize_submit">保存して続行</string> + <string name="ftue_personalize_complete_subtitle">設定を保存しました。</string> + <string name="ftue_profile_picture_subtitle">これは後から変更できます。</string> + <string name="ftue_profile_picture_title">プロフィール画像を追加</string> + <string name="ftue_display_name_entry_footer">これは後から変更できます</string> + <string name="ftue_display_name_entry_title">表示名</string> + <string name="ftue_display_name_subtitle">メッセージを送信する際に表示されます。</string> + <string name="a11y_location_share_option_pinned_icon">この位置情報を共有</string> + <string name="location_share_option_pinned">この位置情報を共有</string> + <string name="a11y_location_share_option_user_live_icon">位置情報(ライブ)を共有</string> + <string name="location_share_option_user_live">位置情報(ライブ)を共有</string> + <string name="location_share_live_stop">中止</string> + <string name="ftue_display_name_title">表示名を選択</string> + <string name="ftue_account_created_subtitle">あなたのアカウント %s が作成されました。</string> + <string name="ftue_account_created_congratulations_title">おめでとうございます!</string> + <string name="threads_notice_migration_message">近日中にスレッドはベータ版となります。 +\n +\nその準備として、この時点以前に作成されたスレッドは、通常の返信として表示するように変更します。 +\n +\nスレッドはMatrixの仕様の一部になったため、これは一度限りの変更です。</string> + <string name="threads_notice_migration_title">スレッドはベータ版になります 🎉</string> + <string name="action_disable">無効にする</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-ko/strings.xml b/vector/src/main/res/values-ko/strings.xml index 900fa23a1c..b57bfd40d7 100644 --- a/vector/src/main/res/values-ko/strings.xml +++ b/vector/src/main/res/values-ko/strings.xml @@ -20,10 +20,10 @@ <string name="notice_placed_voice_call">%s님이 음성 통화를 걸었습니다.</string> <string name="notice_answered_call">%s님이 전화를 받았습니다.</string> <string name="notice_ended_call">%s님이 전화를 끊었습니다.</string> - <string name="notice_made_future_room_visibility">%1$s님이 이후 %2$s에게 방 기록을 공개했습니다</string> - <string name="notice_room_visibility_invited">초대된 시점부터 모든 방 구성원.</string> - <string name="notice_room_visibility_joined">들어온 시점부터 모든 방 구성원.</string> - <string name="notice_room_visibility_shared">모든 방 구성원.</string> + <string name="notice_made_future_room_visibility">%1$s님이 이 시점 이후 방 기록을 %2$s님이 볼 수 있도록 공개했습니다</string> + <string name="notice_room_visibility_invited">방 참여자 모두, 다만 초대받은 시점부터.</string> + <string name="notice_room_visibility_joined">방 참여자 모두, 다만 들어온 시점부터.</string> + <string name="notice_room_visibility_shared">방 참여자 모두.</string> <string name="notice_room_visibility_world_readable">누구나.</string> <string name="notice_room_update">%s님이 방을 업그레이드했습니다.</string> <string name="notice_avatar_changed_too">(아바타도 변경됨)</string> @@ -39,7 +39,6 @@ <string name="medium_phone_number">전화번호</string> <string name="room_displayname_room_invite">방 초대</string> <string name="room_displayname_two_members">%1$s님과 %2$s님</string> - <string name="room_displayname_empty_room">빈 방</string> <string name="initial_sync_start_importing_account">초기 동기화: \n계정 가져오는 중…</string> @@ -134,7 +133,6 @@ <string name="done">완료</string> <string name="action_sign_out_confirmation_simple">정말 로그아웃하시겠습니까\?</string> <string name="action_mark_room_read">읽음으로 표시</string> - <string name="groups_header">커뮤니티</string> <string name="send_bug_report_app_crashed">최근에 애플리케이션이 충돌한 것 같습니다. 충돌 보고서를 열까요\?</string> <string name="username">사용자 이름</string> @@ -145,7 +143,6 @@ <string name="auth_invalid_login_param">알맞지 않은 사용자 이름이나 비밀번호</string> <string name="auth_invalid_email">올바른 이메일 주소가 아닙니다</string> <string name="auth_forgot_password">비밀번호를 잊어버리셨나요\?</string> - <string name="notification_listening_for_events">이벤트 청취하기</string> <string name="sign_out_bottom_sheet_warning_backing_up">키 백업이 진행 중입니다. 지금 로그아웃하면 암호화된 메시지에 접근할 수 없습니다.</string> <string name="sign_out_bottom_sheet_warning_backup_not_active">암호화된 메시지에 대한 접근을 읽지 않도록 모든 장치에서 보안 키 백업이 활성화되어 있어야 합니다.</string> @@ -153,7 +150,6 @@ <string name="sign_out_bottom_sheet_backing_up_keys">키 백업 중…</string> <string name="sign_out_bottom_sheet_will_lose_secure_messages">로그아웃하기 전에 키를 백업하지 않으면 암호화된 메시지에 접근할 수 없습니다.</string> <string name="later">후</string> - <string name="action_accept">수락하기</string> <string name="action_ignore">차단</string> <string name="invitations_header">초대</string> @@ -168,7 +164,6 @@ <string name="error_no_external_application_found">죄송합니다, 이 작업을 완료하기 위한 외부 애플리케이션이 없습니다.</string> <string name="auth_login_sso">통합 인증으로 로그인</string> <string name="auth_email_already_defined">이 이메일 주소는 이미 정의되었습니다.</string> - <string name="auth_recaptcha_message">이 홈서버는 당신이 로봇인지 아닌 지를 확인하고 싶습니다</string> <string name="auth_reset_password_missing_email">계정에 연결된 이메일 주소를 입력해야 합니다.</string> <string name="auth_reset_password_error_unauthorized">이메일 주소를 확인할 수 없습니다: 이메일에 있는 링크를 클릭했는 지 확인하세요</string> @@ -199,14 +194,10 @@ <string name="video_call_in_progress">영상 통화 진행 중…</string> <string name="call_error_user_not_responding">상대방이 전화를 받지 못했습니다.</string> <string name="permissions_rationale_popup_title">정보</string> - - <string name="permissions_rationale_msg_record_audio">음성 통화를 하려면 ${app_name}은 마이크에 접근하는 권한이 필요합니다.</string> - <string name="permissions_rationale_msg_camera_and_audio">영상 통화를 하려면 ${app_name}은 카메라와 마이크에 접근하는 권한이 필요합니다. \n \n전화를 하려면 다음 팝업에서 접근을 허용해주세요.</string> - <string name="yes">네</string> <string name="no">아니오</string> <string name="_continue">계속</string> @@ -215,15 +206,9 @@ <string name="action_reject">받지 않기</string> <string name="list_members">구성원 목록</string> <string name="room_jump_to_first_unread">읽지 않은 첫 부분으로 이동하기.</string> - - <plurals name="room_title_members"> <item quantity="other">%d명의 구성원</item> </plurals> - - - - <string name="room_participants_leave_prompt_title">방 떠나기</string> <string name="room_participants_leave_prompt_msg">방을 떠나겠습니까\?</string> <string name="room_participants_header_direct_chats">다이렉트 대화</string> @@ -258,12 +243,9 @@ <plurals name="room_details_selected"> <item quantity="other">%d개 선택됨</item> </plurals> - <string name="search_hint">검색</string> <string name="search_members_hint">방 구성원 필터</string> <string name="search_no_results">결과 없음</string> - - <string name="room_settings_all_messages">모든 메시지</string> <string name="room_settings_add_homescreen_shortcut">홈 화면에 단축 아이콘 추가</string> <string name="settings_profile_picture">프로필 사진</string> @@ -396,7 +378,6 @@ <string name="settings_send_message_with_enter_summary">가상 키보드의 엔터 버튼으로 줄 바꿈을 하는 대신 메시지를 보냅니다</string> <string name="settings_deactivate_account_section">계정 비활성화</string> <string name="settings_deactivate_my_account">내 계정 비활성화</string> - <string name="settings_analytics">정보 분석</string> <string name="settings_opt_in_of_analytics">정보 분석 데이터 보내기</string> <string name="settings_opt_in_of_analytics_summary">${app_name}은 애플리케이션을 개선할 수 있도록 익명의 분석을 수집합니다.</string> @@ -405,7 +386,6 @@ <string name="devices_details_device_name">공개 이름 업데이트</string> <string name="devices_details_last_seen_title">마지막으로 본 순간</string> <string name="devices_details_last_seen_format">%1$s @ %2$s</string> - <string name="devices_delete_dialog_title">인증</string> <string name="settings_logged_in">이것으로 로그인</string> <string name="settings_home_server">홈서버</string> @@ -453,7 +433,6 @@ <string name="room_settings_labs_warning_message">예기치 않은 방식으로 중단될 수 있는 실험적인 기능들입니다. 주의해서 사용하세요.</string> <string name="room_settings_set_main_address">메인 주소로 설정</string> <string name="room_settings_unset_main_address">메인 주소로 설정 해제</string> - <string name="settings_theme">테마</string> <string name="encryption_information_decryption_error">암호 복호화 오류</string> <string name="encryption_information_device_name">공개 이름</string> @@ -464,7 +443,6 @@ <string name="encryption_export_room_keys_summary">로컬 파일로 키 내보내기</string> <string name="encryption_export_export">내보내기</string> <string name="encryption_export_notice">내보낸 키를 암호화하는 암호를 만드세요. 키를 가져오려면 같은 암호를 입력해야 합니다.</string> - <string name="encryption_message_recovery">암호화된 메시지 복구</string> <string name="encryption_settings_manage_message_recovery_summary">키 백업 관리</string> <string name="encryption_import_e2e_room_keys">종단간 암호화 방 키 가져오기</string> @@ -479,7 +457,6 @@ <string name="encryption_information_verify">확인</string> <string name="encryption_information_verify_device_warning">이 기기가 신뢰할 수 있는 지 확인하려면, 다른 방법을 사용하여 소유자에게 연락하세요 (예: 현실에서 혹은 전화로) 그리고 이 기기의 사용자 설정에서 표시된 키가 아래에 있는 키와 맞는지 물어보세요:</string> <string name="encryption_information_verify_device_warning2">그것이 맞다면, 아래의 확인 버튼을 누르세요. 맞지 않다면, 다른 사람이 이 기기를 가로채고 있는 것이고 블랙리스트에 올려야 합니다. 앞으로 이 확인 절차는 더 정교해질 것입니다.</string> - <string name="select_room_directory">방 목록 선택</string> <string name="directory_server_placeholder">홈서버 URL</string> <string name="directory_server_all_rooms_on_server">%s 서버의 모든 방</string> @@ -487,7 +464,6 @@ <plurals name="notification_unread_notified_messages"> <item quantity="other">%d개의 읽지 않은 알림 메시지</item> </plurals> - <plurals name="notification_unread_notified_messages_in_room_rooms"> <item quantity="other">%d개의 방</item> </plurals> @@ -569,8 +545,6 @@ <string name="group_details_home">홈</string> <string name="rooms">방</string> <string name="invited">초대받음</string> - - <string name="has_been_removed">%2$s님에 의해 %1$s 방에서 추방당했습니다</string> <string name="has_been_banned">%2$s님에 의해 %1$s 방에서 출입 금지당했습니다</string> <string name="reason_colon">이유: %1$s</string> @@ -636,7 +610,6 @@ <string name="keys_backup_setup_step3_copy_button_title">복구 키 저장</string> <string name="keys_backup_setup_step3_share_recovery_file">공유</string> <string name="keys_backup_setup_step3_save_button_title">파일로 저장</string> - <string name="keys_backup_setup_override_backup_prompt_tile">백업이 이미 홈서버에 존재합니다</string> <string name="keys_backup_setup_override_backup_prompt_description">이미 키 백업을 다른 기기에 설정한 모양입니다. 만들고 있는 것으로 바꾸겠습니까\?</string> <string name="keys_backup_setup_override_replace">바꾸기</string> @@ -687,7 +660,6 @@ <string name="keys_backup_settings_checking_backup_state">백업 상태 확인하기</string> <string name="keys_backup_settings_delete_confirm_title">백업 삭제</string> <string name="keys_backup_settings_delete_confirm_message">서버에서 백업한 암호화 키를 삭제하겠습니까\? 더 이상 복구 키를 사용해 암호화된 메시지 기록을 읽을 수 없습니다.</string> - <string name="keys_backup_banner_recover_line1">암호화된 메시지를 잃지 마세요</string> <string name="keys_backup_banner_recover_line2">키 백업하기</string> <string name="keys_backup_banner_update_line1">새 암호화된 메시지 키</string> @@ -700,11 +672,8 @@ <string name="keys_backup_info_title_version">버전</string> <string name="keys_backup_info_title_algorithm">알고리즘</string> <string name="keys_backup_info_title_signature">서명</string> - <string name="sas_verified">확인되었습니다!</string> <string name="sas_got_it">알겠습니다</string> - - <string name="sas_incoming_request_notif_title">확인 요청</string> <string name="sas_incoming_request_notif_content">%s님이 당신의 기기를 확인하고 싶습니다</string> <string name="sas_error_unknown">알 수 없는 오류</string> @@ -795,7 +764,6 @@ <string name="none">없음</string> <string name="action_revoke">취소</string> <string name="action_disconnect">연결 해제</string> - <string name="login_error_homeserver_not_found">이 URL로는 홈서버에 접근할 수 없습니다, 확인해주세요</string> <string name="settings_background_fdroid_sync_mode">백그라운드 동기화 모드 (실험적)</string> <string name="settings_background_fdroid_sync_mode_battery">배터리에 최적화됨</string> @@ -806,7 +774,6 @@ \n이는 라디오와 배터리 사용에 영향을 주며 ${app_name}이 이벤트를 수신하고 있는 상태라는 알림이 영구적으로 표시됩니다.</string> <string name="settings_background_fdroid_sync_mode_disabled">백그라운드 동기화 없음</string> <string name="settings_background_fdroid_sync_mode_disabled_description">앱이 백그라운드에 있을 때 수신 메시지의 알림을 받지 않습니다.</string> - <string name="settings_discovery_category">탐색</string> <string name="settings_discovery_manage">탐색 설정을 관리합니다.</string> <string name="identity_server_not_defined">ID 서버를 사용하고 있지 않습니다</string> @@ -875,7 +842,6 @@ <string name="content_reported_as_inappropriate_content">이 내용을 부적절한 문자로 신고했습니다. \n \n이 사용자의 내용을 더 이상 보고 싶지 않다면, 사용자를 차단하거나 메시지를 감출 수 있습니다.</string> - <string name="settings_integrations">통합</string> <string name="settings_integration_allow">통합 수락</string> <string name="create_space_topic_hint">설명</string> @@ -982,4 +948,21 @@ <string name="notice_room_topic_changed_by_you">주제를 다음으로 변경했습니다: %1$s</string> <string name="notice_display_name_removed_by_you">표시 이름을 삭제했습니다 (이전 이름: %1$s)</string> <string name="notice_display_name_changed_from_by_you">표시 이름을 %1$s에서 %2$s(으)로 변경했습니다</string> + <string name="notice_room_server_acl_set_title_by_you">서버 접근제어목록을 설정했습니다.</string> + <string name="notice_room_server_acl_set_title">%s님이 서버 접근제어목록을 설정했습니다.</string> + <string name="notice_direct_room_update_by_you">이곳을 업그레이드했습니다.</string> + <string name="notice_direct_room_update">%s님이 이곳을 업그레이드했습니다.</string> + <string name="notice_room_update_by_you">방을 업그레이드했습니다.</string> + <string name="notice_made_future_direct_room_visibility_by_you">이 시점 이후 메시지를 %1$s님이 볼 수 있도록 공개했습니다</string> + <string name="notice_made_future_direct_room_visibility">%1$s님이 이 시점 이후 메시지를 %2$s님이 볼 수 있도록 공개했습니다</string> + <string name="notice_made_future_room_visibility_by_you">이 시점 이후 방 기록을 %1$s님이 볼 수 있도록 공개했습니다</string> + <string name="notice_ended_call_by_you">전화를 끊었습니다.</string> + <string name="notice_answered_call_by_you">전화를 받았습니다.</string> + <string name="notice_call_candidates_by_you">통화 연결을 위한 데이터를 보냈습니다.</string> + <string name="notice_call_candidates">%s님이 통화 연결을 위한 데이터를 보냈습니다.</string> + <string name="notice_placed_voice_call_by_you">음성 통화를 시작했습니다.</string> + <string name="notice_placed_video_call_by_you">영상 통화를 시작했습니다.</string> + <string name="notice_room_name_changed_by_you">방 이름을 바꾸었습니다: %1$s</string> + <string name="notice_room_avatar_changed_by_you">방 사진을 바꾸었습니다</string> + <string name="notice_room_avatar_changed">%1$s님이 방 사진을 바꾸었습니다</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-nl/strings.xml b/vector/src/main/res/values-nl/strings.xml index a87aeefe2e..80f819157e 100644 --- a/vector/src/main/res/values-nl/strings.xml +++ b/vector/src/main/res/values-nl/strings.xml @@ -32,14 +32,13 @@ <string name="notice_room_third_party_registered_invite">%1$s heeft de uitnodiging voor %2$s aanvaard</string> <string name="notice_crypto_unable_to_decrypt">** Kan niet ontsleutelen: %s **</string> <string name="notice_crypto_error_unknown_inbound_session_id">Het apparaat van de afzender heeft geen sleutels voor dit bericht gestuurd.</string> - <string name="unable_to_send_message">Kan bericht niet verzenden</string> + <string name="unable_to_send_message">Kan bericht niet versturen</string> <string name="matrix_error">Matrix-fout</string> <string name="medium_email">E-mailadres</string> <string name="medium_phone_number">Telefoonnummer</string> <string name="room_displayname_room_invite">Gespreksuitnodiging</string> <string name="room_displayname_two_members">%1$s en %2$s</string> <string name="room_displayname_empty_room">Leeg gesprek</string> - <string name="initial_sync_start_importing_account">Initiële synchronisatie: \nAccount wordt geïmporteerd…</string> <string name="initial_sync_start_importing_account_crypto">Initiële synchronisatie: @@ -101,7 +100,6 @@ <string name="action_delete">Verwijderen</string> <string name="action_rename">Hernoemen</string> <string name="report_content">Inhoud melden</string> - <string name="or">of</string> <string name="action_invite">Uitnodigen</string> <string name="action_sign_out">Afmelden</string> @@ -124,7 +122,6 @@ <string name="matrix_only_filter">Alleen Matrix-contacten</string> <string name="no_result_placeholder">Geen resultaten</string> <string name="rooms_header">Gesprekken</string> - <string name="send_bug_report_include_logs">Logboek versturen</string> <string name="send_bug_report_include_crash_logs">Crash-logboek versturen</string> <string name="send_bug_report_include_screenshot">Schermafdruk versturen</string> @@ -134,13 +131,13 @@ <string name="send_bug_report_logs_description">Om het probleem te kunnen onderzoeken worden logboeken van deze cliënt met de foutmelding verstuurd. Deze foutmelding, inclusief de logboeken en schermafdruk, zullen niet openbaar zichtbaar zijn. Indien u liever alleen de bovenstaande tekst verstuurt, haal dan het vinkje weg:</string> <string name="send_bug_report_alert_message">Het ziet er naar uit dat u de telefoon in frustratie schudt. Wilt u een probleem melden\?</string> <string name="send_bug_report_sent">De foutmelding is verzonden</string> - <string name="send_bug_report_failed">Verzenden van foutmelding is mislukt (%s)</string> + <string name="send_bug_report_failed">Versturen van foutmelding is mislukt (%s)</string> <string name="send_bug_report_progress">Voortgang (%s%%)</string> <string name="send_bug_report_app_crashed">De toepassing is de vorige keer gecrasht. Wilt u dit melden\?</string> <string name="join_room">Gesprek toetreden</string> - <string name="username">Gebruikersnaam</string> + <string name="username">Inlognaam</string> <string name="logout">Afmelden</string> - <string name="hs_url">Thuisserver-URL</string> + <string name="hs_url">Server-URL</string> <string name="search">Zoeken</string> <string name="start_voice_call">Spraakoproep beginnen</string> <string name="start_video_call">Video-oproep beginnen</string> @@ -148,15 +145,13 @@ <string name="option_take_photo_video">Foto of video maken</string> <string name="auth_login">Aanmelden</string> <string name="auth_submit">Indienen</string> - <string name="auth_invalid_login_param">Verkeerde gebruikersnaam en/of wachtwoord</string> + <string name="auth_invalid_login_param">Verkeerde inlognaam en/of wachtwoord</string> <string name="auth_invalid_email">Dit is geen geldig e-mailadres</string> <string name="auth_email_already_defined">Dit e-mailadres is al in gebruik.</string> <string name="auth_forgot_password">Wachtwoord vergeten?</string> - - <string name="auth_recaptcha_message">Deze thuisserver wil graag weten of u geen robot bent</string> + <string name="auth_recaptcha_message">Deze server wil graag weten of u geen robot bent</string> <string name="auth_reset_password_missing_email">Het e-mailadres dat aan uw account gekoppeld is moet ingevoerd worden.</string> <string name="auth_reset_password_error_unauthorized">Verifiëren van het e-mailadres is mislukt: zorg dat u op de koppeling in de e-mail hebt geklikt</string> - <string name="login_error_invalid_home_server">Voer een geldige URL in</string> <string name="login_error_bad_json">Ongeldige JSON</string> <string name="login_error_not_json">Bevatte geen geldige JSON</string> @@ -172,14 +167,10 @@ <string name="call_in_progress">Oproep gaande…</string> <string name="call_error_user_not_responding">De andere kant heeft niet opgenomen.</string> <string name="permissions_rationale_popup_title">Informatie</string> - - <string name="permissions_rationale_msg_record_audio">${app_name} heeft toegang nodig tot uw microfoon om spraakoproepen te maken.</string> - <string name="permissions_rationale_msg_camera_and_audio">${app_name} heeft toegang nodig tot uw camera en microfoon om video-oproepen te maken. \n \nVerleen toegang op de volgende pop-ups om de oproep te maken.</string> - <string name="yes">JA</string> <string name="no">NEE</string> <string name="_continue">Verdergaan</string> @@ -187,17 +178,16 @@ <string name="action_join">Toetreden</string> <string name="action_reject">Afwijzen</string> <string name="room_jump_to_first_unread">Ga naar ongelezen</string> - <string name="room_participants_leave_prompt_title">Gesprek verlaten</string> <string name="room_participants_leave_prompt_msg">Weet u zeker dat u het gesprek wilt verlaten\?</string> <string name="room_participants_header_direct_chats">TWEEGESPREKKEN</string> <string name="room_participants_action_invite">Uitnodigen</string> <string name="room_participants_action_ban">Verbannen</string> <string name="room_participants_action_unban">Ontbannen</string> - <string name="room_participants_action_ignore">Alle berichten van deze gebruiker verbergen</string> - <string name="room_participants_action_unignore">Alle berichten van deze gebruiker tonen</string> + <string name="room_participants_action_ignore">Alle berichten van deze persoon verbergen</string> + <string name="room_participants_action_unignore">Alle berichten van deze persoon tonen</string> <string name="room_participants_action_mention">Vermelden</string> - <string name="room_participants_power_level_prompt">U kunt deze veranderingen niet ongedaan maken aangezien u de gebruiker tot hetzelfde niveau als uzelf promoveert. + <string name="room_participants_power_level_prompt">U kunt deze veranderingen niet ongedaan maken aangezien u de persoon tot hetzelfde niveau als uzelf promoveert. \nWeet u het zeker\?</string> <string name="room_one_user_is_typing">%s is aan het typen…</string> <string name="room_two_users_are_typing">%1$s en %2$s zijn aan het typen…</string> @@ -214,7 +204,6 @@ <string name="ssl_unexpected_existing_expl">Het certificaat is veranderd van één dat door uw telefoon werd vertrouwd naar een ander. Dit is HEEL ONGEBRUIKELIJK. Het wordt aangeraden om dit nieuwe certificaat NIET TE AANVAARDEN.</string> <string name="ssl_expected_existing_expl">Het certificaat is veranderd van een vertrouwd naar een onvertrouwd certificaat. De server heeft misschien zijn certificaat vernieuwd. Contacteer de serverbeheerder voor de verwachte vingerafdruk.</string> <string name="ssl_only_accept">Aanvaard het certificaat alleen als de serverbeheerder een vingerafdruk heeft gepubliceerd die overeenkomt met degene hierboven.</string> - <string name="search_hint">Zoeken</string> <string name="search_members_hint">Gespreksleden filteren</string> <string name="search_no_results">Geen resultaten</string> @@ -241,9 +230,9 @@ <string name="settings_copyright">Copyright</string> <string name="settings_privacy_policy">Privacybeleid</string> <string name="settings_clear_cache">Cache wissen</string> - <string name="settings_user_settings">Gebruikersinstellingen</string> + <string name="settings_user_settings">Persoonsinstellingen</string> <string name="settings_notifications">Meldingen</string> - <string name="settings_ignored_users">Genegeerde gebruikers</string> + <string name="settings_ignored_users">Genegeerde personen</string> <string name="settings_other">Overige</string> <string name="settings_advanced">Geavanceerd</string> <string name="settings_cryptography">Cryptografie</string> @@ -259,10 +248,9 @@ <string name="devices_details_device_name">Publieke naam bijwerken</string> <string name="devices_details_last_seen_title">Laatst gezien</string> <string name="devices_details_last_seen_format">%1$s @ %2$s</string> - <string name="devices_delete_dialog_title">Authenticatie</string> <string name="settings_logged_in">Aangemeld als</string> - <string name="settings_home_server">Thuisserver</string> + <string name="settings_home_server">Server</string> <string name="settings_identity_server">Identiteitsserver</string> <string name="account_email_validation_message">Bekijk uw e-mail en tik op de koppeling erin. Tik zodra dit gedaan is op Verdergaan.</string> <string name="account_email_already_used_error">Dit e-mailadres is al in gebruik.</string> @@ -283,14 +271,13 @@ <string name="room_settings_read_history_entry_members_only_option_time_shared">Alleen deelnemers (vanaf het moment dat deze optie wordt geselecteerd)</string> <string name="room_settings_read_history_entry_members_only_invited">Alleen deelnemers (vanaf het moment dat ze worden uitgenodigd)</string> <string name="room_settings_read_history_entry_members_only_joined">Alleen deelnemers (vanaf het moment dat ze toetreden)</string> - <string name="room_settings_banned_users_title">Verbannen gebruikers</string> + <string name="room_settings_banned_users_title">Verbannen personen</string> <string name="room_settings_category_advanced_title">Geavanceerd</string> <string name="room_settings_room_internal_id">Interne ID van dit gesprek</string> <string name="room_settings_labs_pref_title">Experimenteel</string> <string name="room_settings_labs_warning_message">Dit zijn experimentele functies die zich op onverwachte manieren kunnen gedragen. Wees behoedzaam bij het gebruik van deze functies.</string> <string name="room_settings_set_main_address">Instellen als hoofdadres</string> <string name="room_settings_unset_main_address">Niet instellen als hoofdadres</string> - <string name="encryption_information_decryption_error">Ontsleutelingsfout</string> <string name="encryption_information_device_name">Publieke naam</string> <string name="encryption_information_device_id">Sessie ID</string> @@ -301,7 +288,6 @@ <string name="encryption_export_export">Exporteren</string> <string name="passphrase_enter_passphrase">Voer wachtwoord in</string> <string name="passphrase_confirm_passphrase">Wachtwoord bevestigen</string> - <string name="encryption_import_e2e_room_keys">E2E-gesprekssleutels importeren</string> <string name="encryption_import_room_keys">Gesprekssleutels importeren</string> <string name="encryption_import_room_keys_summary">Importeer de sleutels uit een lokaal bestand</string> @@ -311,11 +297,10 @@ <string name="encryption_information_not_verified">NIET geverifieerd</string> <string name="encryption_information_verified">Geverifieerd</string> <string name="encryption_information_verify">Verifiëren</string> - <string name="encryption_information_verify_device_warning">Om te verifiëren dat deze sessie vertrouwd kan worden, contacteert u de eigenaar via een andere methode (bv. persoonlijk of via een telefoontje) en vraagt u hem/haar of de sleutel die hij/zij ziet in zijn/haar Gebruikersinstellingen van deze sessie overeenkomt met de sleutel hieronder:</string> + <string name="encryption_information_verify_device_warning">Om te verifiëren dat deze sessie vertrouwd kan worden, contacteert u de eigenaar via een andere methode (bv. persoonlijk of via een telefoontje) en vraagt u hem/haar of de sleutel die hij/zij ziet in zijn/haar persoonsinstellingen van deze sessie overeenkomt met de sleutel hieronder:</string> <string name="encryption_information_verify_device_warning2">Als het overeenkomt, drukt u op de knop ‘Verifiëren’ hieronder. Als het niet overeenkomt, dan onderschept iemand anders deze sessie en zou u het beter blokkeren. In de toekomst zal dit verificatieproces verbeterd worden.</string> - <string name="select_room_directory">Kies een gesprekscatalogus</string> - <string name="directory_server_placeholder">Thuisserver-naam</string> + <string name="directory_server_placeholder">Servernaam</string> <string name="directory_server_all_rooms_on_server">Alle gesprekken op server %s</string> <string name="directory_server_native_rooms">Alle lokale gesprekken op %s</string> <string name="settings_start_on_boot">Starten bij opstarten</string> @@ -361,7 +346,7 @@ <string name="option_take_video">Video maken</string> <string name="call">Bellen</string> <string name="settings_containing_my_display_name">Berichten die mijn weergavenaam bevatten</string> - <string name="settings_containing_my_user_name">Berichten die mijn gebruikersnaam bevatten</string> + <string name="settings_containing_my_user_name">Berichten die mijn inlognaam bevatten</string> <string name="settings_analytics">Statistische gegevens</string> <string name="settings_labs_native_camera">Systeemcamera gebruiken</string> <string name="you_added_a_new_device">U heeft een nieuwe sessie ‘%s’ toegevoegd, die versleutelingssleutels aanvraagt.</string> @@ -381,25 +366,21 @@ <item quantity="one">%d verandering in lidmaatschap</item> <item quantity="other">%d veranderingen in lidmaatschap</item> </plurals> - <string name="list_members">Ledenlijst</string> - + <string name="list_members">Leden</string> <plurals name="room_title_members"> <item quantity="one">%d deelnemer</item> <item quantity="other">%d deelnemers</item> </plurals> - <string name="room_participants_ban_prompt_msg">Als een gebruiker wordt verbannen, wordt deze uit deze kamer verwijderd en wordt er voorkomen dat hij opnieuw lid wordt.</string> + <string name="room_participants_ban_prompt_msg">Als een persoon wordt verbannen, wordt deze uit deze kamer verwijderd en wordt er voorkomen dat hij opnieuw lid wordt.</string> <plurals name="room_new_messages_notification"> <item quantity="one">%d nieuw bericht</item> <item quantity="other">%d nieuwe berichten</item> </plurals> - - <string name="room_settings_all_messages">Alle berichten</string> <string name="room_settings_add_homescreen_shortcut">Snelkoppeling aan thuisscherm toevoegen</string> <string name="settings_inline_url_preview">Inline URL-voorvertoning</string> - <string name="settings_vibrate_on_mention">Trillen bij vermelden van een gebruiker</string> + <string name="settings_vibrate_on_mention">Trillen bij vermelden van een persoon</string> <string name="settings_flair">Badge</string> - <plurals name="notification_unread_notified_messages_in_room_rooms"> <item quantity="one">%d gesprek</item> <item quantity="other">%d gesprekken</item> @@ -431,15 +412,15 @@ <string name="settings_opt_in_of_analytics">Statistische gegevens (analytics) versturen</string> <string name="settings_opt_in_of_analytics_summary">${app_name} verzamelt anonieme statistische gegevens (analytics) om het voor ons mogelijk te maken om de app te verbeteren.</string> <string name="widget_integration_missing_parameter">Er ontbreekt een vereiste parameter.</string> - <string name="dialog_user_consent_content">Om de %1$s-thuisserver verder te blijven gebruiken, dient u de voorwaarden te lezen en ermee akkoord te gaan.</string> + <string name="dialog_user_consent_content">Om de %1$s-server verder te blijven gebruiken, dient u de voorwaarden te lezen en ermee akkoord te gaan.</string> <string name="dialog_user_consent_submit">Nu doorlezen</string> <string name="deactivate_account_title">Account deactiveren</string> - <string name="deactivate_account_content">Dit zal uw account voorgoed onbruikbaar maken. U zult zich niet meer kunnen aanmelden, en niemand anders zal met dezelfde gebruikers-ID kunnen registreren. Dit zal er voor zorgen dat uw account alle gesprekken verlaat waar deze momenteel lid van is, en het verwijdert de accountgegevens van de identiteitsserver. <b>Deze actie is onomkeerbaar.</b> -\n -\nHet deactiveren van uw account <b>zal er niet standaard voor zorgen dat de berichten die u hebt verzonden worden vergeten.</b> Indien u wilt dat wij de berichten vergeten, vinkt u het vakje hieronder aan. -\n + <string name="deactivate_account_content">Dit zal uw account voorgoed onbruikbaar maken. U zult zich niet meer kunnen aanmelden, en niemand anders zal met dezelfde persoon-ID kunnen registreren. Dit zal er voor zorgen dat uw account alle gesprekken verlaat waar deze momenteel lid van is, en het verwijdert de accountgegevens van de identiteitsserver. <b>Deze actie is onomkeerbaar.</b> +\n +\nHet deactiveren van uw account <b>zal er niet standaard voor zorgen dat de berichten die u hebt verzonden worden vergeten.</b> Indien u wilt dat wij de berichten vergeten, vinkt u het vakje hieronder aan. +\n \nDe zichtbaarheid van berichten in Matrix is gelijkaardig aan e-mails. Het vergeten van uw berichten betekent dat berichten die u verstuurd heeft niet meer gedeeld worden met nieuwe of ongeregistreerde gebruikers, maar geregistreerde gebruikers die al toegang hebben tot deze berichten zullen alsnog toegang hebben tot hun eigen kopie ervan.</string> - <string name="deactivate_account_delete_checkbox">Vergeet alle berichten die ik heb verstuurd wanneer mijn account gedeactiveerd is (<b>Let op:</b> dit zal er voor zorgen dat toekomstige gebruikers een onvolledig beeld krijgen van gesprekken)</string> + <string name="deactivate_account_delete_checkbox">Vergeet alle berichten die ik heb verstuurd wanneer mijn account gedeactiveerd is (<b>Let op:</b> dit zal er voor zorgen dat toekomstige personen een onvolledig beeld krijgen van gesprekken)</string> <string name="deactivate_account_submit">Account deactiveren</string> <string name="action_download">Downloaden</string> <string name="e2e_re_request_encryption_key">Beveiligingssleutels van uw sessies <u>opnieuw aanvragen</u>.</string> @@ -450,15 +431,15 @@ <string name="send_bug_report_description_in_english">Beschrijf het probleem in het Engels, indien mogelijk.</string> <string name="settings_preview_media_before_sending">Media bekijken vóór het versturen</string> <string name="command_description_emote">Toont een actie</string> - <string name="command_description_ban_user">Verbant gebruiker met gegeven ID</string> - <string name="command_description_unban_user">Heft verbanning van gebruiker met gegeven ID op</string> - <string name="command_description_op_user">Stel het machtsniveau van een gebruiker in</string> - <string name="command_description_deop_user">Neemt rechten van gebruiker met gegeven ID af</string> - <string name="command_description_invite_user">Nodigt gebruiker met gegeven ID uit in het huidige gesprek</string> + <string name="command_description_ban_user">Verbant persoon met gegeven ID</string> + <string name="command_description_unban_user">Heft verbanning van persoon met gegeven ID op</string> + <string name="command_description_op_user">Stel het machtsniveau van een persoon in</string> + <string name="command_description_deop_user">Neemt rechten van persoon met gegeven ID af</string> + <string name="command_description_invite_user">Nodigt persoon met gegeven ID uit in het huidige gesprek</string> <string name="command_description_join_room">Voegt een kamer toe met het opgegeven adres</string> <string name="command_description_part_room">Gesprek verlaten</string> <string name="command_description_topic">Onderwerp van het gesprek instellen</string> - <string name="command_description_remove_user">Stuurt gebruiker met gegeven ID eruit</string> + <string name="command_description_remove_user">Stuurt persoon met gegeven ID eruit</string> <string name="command_description_nick">Wijzigt uw weergavenaam</string> <string name="command_description_markdown">Markdown aan/uit</string> <string name="room_tombstone_versioned_description">Dit gesprek is vervangen en is niet langer actief.</string> @@ -466,35 +447,29 @@ <string name="room_tombstone_continuation_description">Dit gesprek is een voortzetting van een ander gesprek</string> <string name="room_tombstone_predecessor_link">Klik hier om oudere berichten te zien</string> <string name="system_alerts_header">Systeemmeldingen</string> - - - - <plurals name="room_details_selected"> <item quantity="one">%d geselecteerd</item> <item quantity="other">%d geselecteerd</item> </plurals> <string name="command_description_clear_scalar_token">Om Matrix-appbeheer te herstellen</string> - - <string name="resource_limit_contact_admin">contact op te nemen met uw dienstbeheerder</string> - <string name="resource_limit_soft_default">Deze thuisserver heeft een van zijn bronlimieten overschreden, dus <b>sommige gebruikers zullen zich niet kunnen aanmelden</b>.</string> - <string name="resource_limit_hard_default">Deze thuisserver heeft een van zijn bronlimieten overschreden.</string> - <string name="resource_limit_soft_mau"> Deze thuisserver heeft zijn limiet voor maandelijks actieve gebruikers overschreden, dus <b>sommige gebruikers zullen zich niet kunnen aanmelden</b>.</string> - <string name="resource_limit_hard_mau">Deze thuisserver heeft zijn limiet voor maandelijks actieve gebruikers overschreden.</string> + <string name="resource_limit_soft_default">Deze server heeft een van zijn bronlimieten overschreden, dus <b>sommige personen zullen zich niet kunnen aanmelden</b>.</string> + <string name="resource_limit_hard_default">Deze server heeft een van zijn bronlimieten overschreden.</string> + <string name="resource_limit_soft_mau"> Deze server heeft zijn limiet voor maandelijks actieve personen overschreden, dus <b>sommige personen zullen zich niet kunnen aanmelden</b>.</string> + <string name="resource_limit_hard_mau">Deze server heeft zijn limiet voor maandelijks actieve personen overschreden.</string> <string name="resource_limit_soft_contact">Gelieve %s om deze limiet te verhogen.</string> <string name="resource_limit_hard_contact">Gelieve %s om deze dienst te blijven gebruiken.</string> <string name="dialog_title_error">Foutmelding</string> <string name="action_accept">Aanvaarden</string> - <string name="auth_accept_policies">Gelieve het beleid van deze thuisserver te lezen en aanvaarden:</string> + <string name="auth_accept_policies">Gelieve het beleid van deze server te lezen en aanvaarden:</string> <string name="settings_call_category">Oproepen</string> <string name="settings_call_ringtone_use_app_ringtone">Gebruik de standaardbeltoon van ${app_name} voor inkomende oproepen</string> <string name="settings_call_ringtone_title">Beltoon voor inkomende oproepen</string> <string name="settings_call_ringtone_dialog_title">Selecteer beltoon voor oproepen:</string> <string name="room_participants_action_remove">Eruit sturen</string> - <string name="settings_inline_url_preview_summary">Voorvertoning van koppelingen in het gesprek tonen (als uw thuisserver deze functie ondersteunt).</string> + <string name="settings_inline_url_preview_summary">Voorvertoning van koppelingen in het gesprek tonen (als uw server deze functie ondersteunt).</string> <string name="settings_send_typing_notifs">Typmeldingen versturen</string> - <string name="settings_send_typing_notifs_summary">Laat andere gebruikers weten dat u aan het typen bent.</string> + <string name="settings_send_typing_notifs_summary">Laat andere personen weten dat u aan het typen bent.</string> <string name="settings_send_markdown">Markdown-opmaak</string> <string name="settings_send_markdown_summary">Maak berichten op met Markdown-syntax voordat ze verstuurd worden. Hiermee kunt u uitgebreide opmaak gebruiken, zoals sterretjes voor schuingedrukte tekst.</string> <string name="settings_show_read_receipts">Leesbevestigingen weergeven</string> @@ -558,15 +533,15 @@ <string name="settings_troubleshoot_test_fcm_failed">Het FCM-bewijs is niet opgehaald: \n%1$s</string> <string name="settings_troubleshoot_test_fcm_failed_too_many_registration">[%1$s] -\nDeze fout is onafhankelijk van ${app_name}. Volgens Google betekent deze fout dat het apparaat te veel apps heeft geregistreerd met FCM. De fout treedt enkel op ingeval er een enorm aantal apps is, dus zou dit de gemiddelde gebruiker niet mogen hinderen.</string> +\nDeze fout is onafhankelijk van ${app_name}. Volgens Google betekent deze fout dat het apparaat te veel apps heeft geregistreerd met FCM. De fout treedt enkel op ingeval er een enorm aantal apps is, dus zou dit de gemiddelde persoon niet mogen hinderen.</string> <string name="settings_troubleshoot_test_fcm_failed_service_not_available">[%1$s] \nDeze fout is onafhankelijk van ${app_name}. Ze kan verschillende oorzaken hebben. Misschien werkt het als u het later opnieuw probeert. U kunt ook controleren of het gegevensverbruik van Google Play Services niet wordt beperkt in de systeeminstellingen, of dat de klok van uw apparaat wel juist staat, of dat het misschien aan een aangepaste ROM ligt.</string> <string name="settings_troubleshoot_test_fcm_failed_account_missing">[%1$s] \nDeze fout is onafhankelijk van ${app_name}. Er is geen Google-account verbonden met de telefoon. Open het accountbeheer en voeg er een Google-account toe.</string> <string name="settings_troubleshoot_test_fcm_failed_account_missing_quick_fix">Account toevoegen</string> <string name="settings_troubleshoot_test_token_registration_title">Bewijsregistratie</string> - <string name="settings_troubleshoot_test_token_registration_success">FCM-bewijs geregistreerd bij thuisserver.</string> - <string name="settings_troubleshoot_test_token_registration_failed">FCM-bewijs niet geregistreerd bij thuisserver: + <string name="settings_troubleshoot_test_token_registration_success">FCM-bewijs geregistreerd bij server.</string> + <string name="settings_troubleshoot_test_token_registration_failed">FCM-bewijs niet geregistreerd bij server: \n%1$s</string> <string name="settings_troubleshoot_test_service_boot_title">Starten bij opstarten van apparaat</string> <string name="settings_troubleshoot_test_service_boot_success">De dienst zal starten wanneer het apparaat wordt herstart.</string> @@ -581,7 +556,7 @@ <string name="settings_troubleshoot_test_bg_restricted_quickfix">Beperkingen uitschakelen</string> <string name="settings_troubleshoot_test_battery_title">Accuoptimalisatie</string> <string name="settings_troubleshoot_test_battery_success">${app_name} wordt niet beperkt door accuoptimalisatie.</string> - <string name="settings_troubleshoot_test_battery_failed">Als een gebruiker een apparaat los van de oplader een tijd laat stilliggen, met het scherm uitgeschakeld, gaat het apparaat in slaapmodus. Dit verhindert apps de toegang tot het netwerk, en stelt hun taken, synchronisaties en standaardalarmen uit.</string> + <string name="settings_troubleshoot_test_battery_failed">Als een persoon een apparaat los van de oplader een tijd laat stilliggen, met het scherm uitgeschakeld, gaat het apparaat in slaapmodus. Dit verhindert apps de toegang tot het netwerk, en stelt hun taken, synchronisaties en standaardalarmen uit.</string> <string name="settings_troubleshoot_test_battery_quickfix">Optimalisatie negeren</string> <string name="settings_noisy_notifications_preferences">Lawaaiierige meldingen configureren</string> <string name="settings_call_notifications_preferences">Oproepmeldingen configureren</string> @@ -590,7 +565,6 @@ <string name="settings_cryptography_manage_keys">Beheer van cryptografische sleutels</string> <string name="settings_send_message_with_enter">Berichten versturen met Enter</string> <string name="settings_send_message_with_enter_summary">De Enter-knop van het toetsenbord zal berichten versturen in plaats van een regeleinde in te voegen</string> - <string name="settings_password">Wachtwoord</string> <string name="settings_fail_to_update_password_invalid_current_password">Het wachtwoord is ongeldig</string> <string name="settings_media">Media</string> @@ -621,7 +595,7 @@ <string name="markdown_has_been_enabled">Markdown is ingeschakeld.</string> <string name="markdown_has_been_disabled">Markdown is uitgeschakeld.</string> <string name="notification_silent">Stil</string> - <string name="error_empty_field_enter_user_name">Voer een gebruikersnaam in.</string> + <string name="error_empty_field_enter_user_name">Voer een inlognaam in.</string> <string name="unknown_error">Sorry, er is een fout opgetreden</string> <string name="merged_events_expand">uitvouwen</string> <string name="merged_events_collapse">invouwen</string> @@ -641,7 +615,7 @@ <string name="keys_backup_setup_step1_advanced">(Geavanceerd)</string> <string name="keys_backup_setup_step1_manual_export">Sleutels handmatig exporteren</string> <string name="keys_backup_setup_step2_text_title">Beveilig uw back-up met een wachtwoord.</string> - <string name="keys_backup_setup_step2_text_description">We bewaren een versleutelde kopie van uw sleutels op onze thuisserver. Bescherm uw back-up met een wachtwoord om deze veilig te houden. + <string name="keys_backup_setup_step2_text_description">We bewaren een versleutelde kopie van uw sleutels op onze server. Bescherm uw back-up met een wachtwoord om deze veilig te houden. \n \nVoor een maximale beveiliging zou deze sleutel moeten verschillen van uw accountwachtwoord.</string> <string name="keys_backup_setup_step2_button_title">Wachtwoord instellen</string> @@ -658,7 +632,6 @@ <string name="keys_backup_setup_step3_copy_button_title">Herstelsleutel opslaan</string> <string name="keys_backup_setup_step3_share_recovery_file">Delen</string> <string name="keys_backup_setup_step3_save_button_title">Opslaan als bestand</string> - <string name="keys_backup_setup_step3_please_make_copy">Gelieve er een kopie van te maken</string> <string name="keys_backup_setup_step3_share_intent_chooser_title">Herstelsleutel delen met…</string> <string name="keys_backup_setup_step3_generating_key_status">Herstelsleutel wordt gegenereerd met wachtwoord, dit proces kan enkele seconden duren.</string> @@ -706,7 +679,6 @@ <string name="keys_backup_settings_deleting_backup">Back-up wordt verwijderd…</string> <string name="keys_backup_settings_delete_confirm_title">Back-up verwijderen</string> <string name="keys_backup_settings_delete_confirm_message">Uw geback-upte versleutelingssleutels verwijderen van de server\? U zult uw herstelsleutel niet meer kunnen gebruiken om de versleutelde berichtgeschiedenis te lezen.</string> - <string name="keys_backup_banner_recover_line1">Verlies nooit uw versleutelde berichten</string> <string name="keys_backup_banner_recover_line2">Sleutelback-up gebruiken</string> <string name="keys_backup_banner_update_line1">Nieuwe sleutels voor versleutelde berichten</string> @@ -720,7 +692,6 @@ <string name="keys_backup_info_title_version">Versie</string> <string name="keys_backup_info_title_algorithm">Algoritme</string> <string name="keys_backup_info_title_signature">Ondertekening</string> - <string name="error_jitsi_not_supported_on_old_device">Sorry, vergadergesprekken met Jitsi worden nog niet ondersteund op oudere apparaten (met een Android-versie lager dan 6.0)</string> <string name="encryption_information_unknown_ip">onbekend IP-adres</string> <string name="you_added_a_new_device_with_info">Een nieuwe sessie vraagt versleutelingssleutels aan. @@ -736,8 +707,6 @@ <string name="ignore_request_short_label">Negeren</string> <string name="sas_verified">Geverifieerd!</string> <string name="sas_got_it">Ik snap het</string> - - <string name="sas_incoming_request_notif_title">Verificatieverzoek</string> <string name="sas_incoming_request_notif_content">%s wil uw sessie verifiëren</string> <string name="sas_error_unknown">Onbekende fout</string> @@ -745,9 +714,8 @@ <string name="action_revoke">Intrekken</string> <string name="action_disconnect">Verbinding verbreken</string> <string name="action_decline">Weigeren</string> - <string name="login_error_no_homeserver_found">Dit is geen geldig Matrix-serveradres</string> - <string name="login_error_homeserver_not_found">Kan geen verbinding maken met een thuisserver op deze URL, controleer de URL</string> + <string name="login_error_homeserver_not_found">Kan geen verbinding maken met een server op deze URL, controleer de URL</string> <string name="settings_background_fdroid_sync_mode">Synchroniseren op de achtergrond</string> <string name="settings_background_fdroid_sync_mode_battery">Geoptimaliseerd voor batterij</string> <string name="settings_background_fdroid_sync_mode_battery_description">${app_name} zal op een batterijzuinige manier synchroniseren op de achtergrond. @@ -757,7 +725,6 @@ \nDit heeft een negatieve impact op uw batterij- en datagebruik. Er zal een melding getoond worden ter informatie.</string> <string name="settings_background_fdroid_sync_mode_disabled">Geen achtergrondssynchronisatie</string> <string name="settings_background_fdroid_sync_mode_disabled_description">U zal geen melding van berichten ontvangen als de app zich in de achtergrond bevindt.</string> - <string name="settings_integrations">Integraties</string> <string name="settings_integrations_summary">Gebruik een integratiebeheerder om bots, bruggen, widgets en stickerpakketten te beheren. \nIntegratiebeheerders ontvangen configuratiedata en kunnen widgets aanpassen, gespreksuitnodigingen versturen en bestuursniveaus instellen namens u.</string> @@ -777,7 +744,7 @@ <string name="room_widget_revoke_access">Toegang intrekken voor mij</string> <string name="room_widget_permission_display_name">Uw weergavenaam</string> <string name="room_widget_permission_avatar_url">Uw profielfoto-URL</string> - <string name="room_widget_permission_user_id">Uw gebruikers-ID</string> + <string name="room_widget_permission_user_id">Uw persoon-ID</string> <string name="room_widget_permission_theme">Uw thema</string> <string name="room_widget_permission_widget_id">Widget-ID</string> <string name="room_widget_permission_room_id">Gespreks-ID</string> @@ -788,13 +755,13 @@ <string name="room_widget_webview_access_microphone">Microfoon gebruiken</string> <string name="room_widget_webview_read_protected_media">DRM-beschermde media lezen</string> <string name="widget_integration_review_terms">Om verder te gaan dient u de dienstvoorwaarden te aanvaarden.</string> - <string name="keys_backup_setup_override_backup_prompt_tile">Er bestaat al een back-up op uw thuisserver</string> + <string name="keys_backup_setup_override_backup_prompt_tile">Er bestaat al een back-up op uw server</string> <string name="keys_backup_setup_override_backup_prompt_description">Het lijkt erop dat u al een back-up van uw herstelsleutel heeft uit een andere sessie. Wilt u deze vervangen door degene die u nu aanmaakt\?</string> <string name="keys_backup_setup_override_replace">Vervangen</string> <string name="keys_backup_setup_override_stop">Stoppen</string> <string name="keys_backup_settings_checking_backup_state">Back-upstatus wordt gecontroleerd</string> <string name="identity_server_not_defined">U gebruikt geen identiteitsserver</string> - <string name="error_user_already_logged_in">Het lijkt er op dat u probeert verbinding te maken met een andere thuisserver. Wil je uitloggen\?</string> + <string name="error_user_already_logged_in">Het lijkt er op dat u probeert verbinding te maken met een andere server. Wil je uitloggen\?</string> <string name="edit">Bewerken</string> <string name="reply">Beantwoorden</string> <string name="global_retry">Opnieuw proberen</string> @@ -811,7 +778,7 @@ <string name="message_add_reaction">Reactie Toevoegen</string> <string name="message_view_reaction">Reacties Bekijken</string> <string name="reactions">Reacties</string> - <string name="event_redacted_by_user_reason">Gebeurtenis verwijderd door gebruiker</string> + <string name="event_redacted_by_user_reason">Gebeurtenis verwijderd door persoon</string> <string name="event_redacted_by_admin_reason">Gebeurtenis gemodereerd door gesprek beheerder</string> <string name="malformed_message">Niet correcte gebeurtenis, kan niet weergeven</string> <string name="create_new_room">Maak een nieuw gesprek aan</string> @@ -914,7 +881,7 @@ <string name="notice_direct_room_join">%1$s sluit aan</string> <string name="notice_room_join_by_you">U heeft de kamer betreden</string> <string name="voice_message_tap_to_stop_toast">Druk op uw opname om te stoppen of om te luisteren</string> - <string name="voice_message_release_to_send_toast">Houd ingedrukt om op te nemen, laat los om te verzenden</string> + <string name="voice_message_release_to_send_toast">Houd ingedrukt om op te nemen, laat los om te versturen</string> <string name="a11y_delete_recorded_voice_message">Verwijder opname</string> <string name="a11y_recording_voice_message">Stembericht aan het opnemen</string> <string name="a11y_pause_voice_message">Pauzeer stembericht</string> @@ -989,8 +956,8 @@ <string name="power_level_edit_title">Rol instellen</string> <string name="identity_server_set_default_submit">%1$s gebruiken</string> <string name="choose_locale_current_locale_title">Huidige taal</string> - <string name="invite_users_to_room_title">Gebruikers Uitnodigen</string> - <string name="inviting_users_to_room">Gebruikers uitnodigen…</string> + <string name="invite_users_to_room_title">Personen uitnodigen</string> + <string name="inviting_users_to_room">Personen uitnodigen…</string> <string name="add_members_to_room">Leden toevoegen</string> <string name="crosssigning_verify_session">Login bevestigen</string> <string name="use_file">Bestand Gebruiken</string> @@ -1045,9 +1012,9 @@ <string name="soft_logout_signin_title">Inloggen</string> <string name="seen_by">Gezien door</string> <string name="login_signin_matrix_id_hint">Matrix-ID</string> - <string name="login_error_outdated_homeserver_title">Verouderde thuisserver</string> + <string name="login_error_outdated_homeserver_title">Verouderde server</string> <string name="login_a11y_choose_matrix_org">Selecteer matrix.org</string> - <string name="login_msisdn_confirm_send_again">Opnieuw verzenden</string> + <string name="login_msisdn_confirm_send_again">Opnieuw versturen</string> <string name="login_msisdn_confirm_hint">Code invoeren</string> <string name="login_set_msisdn_mandatory_hint">Telefoonnummer</string> <string name="login_set_email_optional_hint">Email (optioneel)</string> @@ -1058,23 +1025,23 @@ <string name="timeline_unread_messages">Ongelezen berichten</string> <string name="room_list_quick_actions_notifications_mentions">Alleen vermeldingen</string> <string name="settings_secure_backup_section_title">Beveiligde Backup</string> - <string name="room_participants_unban_title">Verbanning gebruiker ongedaan maken</string> - <string name="room_participants_ban_title">Gebruiker verbannen</string> - <string name="room_participants_remove_title">Gebruiker verwijderen</string> + <string name="room_participants_unban_title">Verbanning persoon ongedaan maken</string> + <string name="room_participants_ban_title">Persoon verbannen</string> + <string name="room_participants_remove_title">Persoon verwijderen</string> <string name="room_participants_action_cancel_invite_title">Uitnodiging annuleren</string> - <string name="room_participants_action_unignore_title">Gebruiker niet meer negeren</string> + <string name="room_participants_action_unignore_title">Persoon niet meer negeren</string> <string name="sent_a_voice_message">Stem</string> <string name="settings_server_room_version_unstable">onstabiel</string> <string name="settings_server_room_version_stable">stabiel</string> <string name="room_list_quick_actions_notifications_all">Alle berichten</string> - <string name="message_ignore_user">Gebruiker negeren</string> + <string name="message_ignore_user">Persoon negeren</string> <string name="content_reported_title">Inhoud gerapporteerd</string> - <string name="block_user">GEBRUIKER NEGEREN</string> + <string name="block_user">PERSOON NEGEREN</string> <string name="report_content_custom">Aangepast rapport…</string> <string name="report_content_inappropriate">Dit is ongepast</string> <string name="report_content_spam">Dit is spam</string> <string name="one_user_read">Gelezen door %s</string> - <string name="send_attachment">Bijlage verzenden</string> + <string name="send_attachment">Bijlage versturen</string> <string name="identity_server">Identiteitsserver</string> <string name="creating_direct_room">Kamer aanmaken…</string> <string name="room_filtering_filter_hint">Gesprekken filteren…</string> @@ -1095,7 +1062,7 @@ <string name="settings_mentions_at_room">\@room</string> <string name="settings_notification_other">Overige</string> <string name="room_settings_none">Geen</string> - <string name="room_participants_action_ignore_title">Gebruiker negeren</string> + <string name="room_participants_action_ignore_title">Persoon negeren</string> <string name="room_participants_power_level_demote_warning_title">Uzelf degraderen\?</string> <string name="room_participants_action_cancel_invite">Uitnodiging annuleren</string> <string name="call_hold_action">In de wacht zetten</string> @@ -1113,7 +1080,7 @@ <string name="space_type_public">Publiek</string> <string name="event_status_a11y_failed">Mislukt</string> <string name="event_status_a11y_sent">Verzonden</string> - <string name="event_status_a11y_sending">Verzenden</string> + <string name="event_status_a11y_sending">Versturen</string> <string name="dev_tools_form_hint_type">Type</string> <string name="a11y_unchecked">Ongecontroleerd</string> <string name="a11y_checked">Gecontroleerd</string> @@ -1121,7 +1088,7 @@ <string name="a11y_video">Video</string> <string name="a11y_image">Afbeelding</string> <string name="a11y_screenshot">Schermafbeelding</string> - <string name="call_transfer_users_tab_title">Gebruikers</string> + <string name="call_transfer_users_tab_title">Personen</string> <string name="call_transfer_title">Overdragen</string> <string name="call_transfer_connect_action">Verbinden</string> <string name="room_settings_topic_hint">Onderwerp</string> @@ -1159,7 +1126,7 @@ <string name="encryption_information_cross_signing_state">Gekruist Ondertekenen</string> <string name="settings_category_timeline">Tijdlijn</string> <string name="unignore">Negeren opheffen</string> - <string name="room_member_power_level_users">Gebruikers</string> + <string name="room_member_power_level_users">Personen</string> <string name="room_member_power_level_invites">Genodigden</string> <string name="room_member_power_level_custom">Aangepast</string> <string name="room_member_power_level_moderators">Moderatoren</string> @@ -1181,7 +1148,7 @@ <string name="login_signup_cancel_confirmation_title">Waarschuwing</string> <string name="login_signup_submit">Volgende</string> <string name="login_signup_password_hint">Wachtwoord</string> - <string name="login_signup_username_hint">Gebruikersnaam</string> + <string name="login_signup_username_hint">Inlognaam</string> <string name="login_msisdn_confirm_submit">Volgende</string> <string name="login_set_msisdn_submit">Volgende</string> <string name="login_set_email_submit">Volgende</string> @@ -1265,30 +1232,30 @@ <string name="login_splash_submit">Aan de slag</string> <string name="space_settings_permissions_title">Spacerechten</string> <string name="room_settings_permissions_title">Gespreksrechten</string> - <string name="space_participants_unban_prompt_msg">Door deze gebruiker niet meer de verbannen kan hij/zij opnieuw toetreden tot de space.</string> - <string name="room_participants_unban_prompt_msg">Door deze gebruiker niet meer de verbannen kan hij/zij opnieuw toetreden tot het gesprek.</string> - <string name="space_participants_ban_prompt_msg">Door deze gebruiker te verbannen zal hij/zij verwijderd worden uit deze space en voorkomen dat hij/zij opnieuw toetreedt.</string> + <string name="space_participants_unban_prompt_msg">Door deze persoon niet meer de verbannen kan hij/zij opnieuw toetreden tot de space.</string> + <string name="room_participants_unban_prompt_msg">Door deze persoon niet meer de verbannen kan hij/zij opnieuw toetreden tot het gesprek.</string> + <string name="space_participants_ban_prompt_msg">Door deze persoon te verbannen zal hij/zij verwijderd worden uit deze space en voorkomen dat hij/zij opnieuw toetreedt.</string> <string name="room_participants_ban_reason">Reden voor verbanning</string> - <string name="space_participants_remove_prompt_msg">door deze gebruiker de verwijderen zal hij/zij niet meer in deze space zitten. + <string name="space_participants_remove_prompt_msg">Door deze persoon de verwijderen zal hij/zij niet meer in deze space zitten. \n \nOm te voorkomen dat hij/zij opnieuw toetreedt, kunt u hem/haar ook verbannen.</string> - <string name="room_participants_remove_prompt_msg">door deze gebruiker te verwijderen zal hij/zij niet meer in dit gesprek zitten. + <string name="room_participants_remove_prompt_msg">Door deze persoon te verwijderen zal hij/zij niet meer in dit gesprek zitten. \n \nOm te voorkomen dat hij/zij opnieuw toetreedt, kun je hem/haar ook verbannen.</string> <string name="room_participants_remove_reason">Reden voor verwijdering</string> - <string name="room_participants_action_cancel_invite_prompt_msg">Weet u zeker dat u uitnodiging voor deze gebruiker wilt annuleren\?</string> - <string name="room_participants_action_unignore_prompt_msg">Het niet meer negeren van deze gebruiker zal al zijn/haar berichten opnieuw doen weergeven.</string> - <string name="room_participants_action_ignore_prompt_msg">Door deze gebruiker te negeren worden zijn/haar berichten verwijderd uit gesprekken die jullie delen. + <string name="room_participants_action_cancel_invite_prompt_msg">Weet u zeker dat u uitnodiging voor deze persoon wilt annuleren\?</string> + <string name="room_participants_action_unignore_prompt_msg">Het niet meer negeren van deze persoon zal al zijn/haar berichten opnieuw doen weergeven.</string> + <string name="room_participants_action_ignore_prompt_msg">Door deze persoon te negeren worden zijn/haar berichten verwijderd uit gesprekken die jullie delen. \n \nU kunt deze actie op elk moment ongedaan maken in de algemene instellingen.</string> - <string name="room_participants_power_level_demote_warning_prompt">U kunt deze wijziging niet ongedaan maken omdat uzelf degradeert, als u de laatste gebruiker met rechten bent in het gesprek zal het onmogelijk zijn om opnieuw rechten te krijgen.</string> + <string name="room_participants_power_level_demote_warning_prompt">U kunt deze wijziging niet ongedaan maken omdat uzelf degradeert, als u de laatste persoon met rechten bent in het gesprek zal het onmogelijk zijn om opnieuw rechten te krijgen.</string> <string name="room_participants_leave_private_warning">Dit gesprek is niet publiek. U kunt niet opnieuw toetreden zonder uitnodiging.</string> <string name="permissions_denied_add_contact">Toegang verlenen tot uw contactpersonen.</string> <string name="permissions_denied_qr_code">Om de QR-code te scannen moet u toegang verlenen tot de camera.</string> <string name="call_remove_jitsi_widget_progress">Oproep beëindigen…</string> <string name="call_ended_invite_timeout_title">Geen antwoord</string> - <string name="call_ended_user_busy_description">De gebruiker die u heeft gebeld is bezig.</string> - <string name="call_ended_user_busy_title">Gebruiker bezig</string> + <string name="call_ended_user_busy_description">De persoon die u heeft gebeld is bezet.</string> + <string name="call_ended_user_busy_title">Persoon bezet</string> <string name="call_held_by_you">U heeft de oproep in de wacht gezet</string> <string name="call_held_by_user">%s heeft de oproep in de wacht gezet</string> <string name="audio_call_with_participant">Bellen met %s</string> @@ -1313,10 +1280,10 @@ <string name="call_format_turn_hd_off">HD uitschakelen</string> <string name="call_select_sound_device">Geluidsapparaat Selecteren</string> <string name="call_failed_no_connection_description">Kan geen realtime verbinding tot stand brengen. -\nVraag de beheerder van uw thuisserver om een TURN-server te configureren om gesprekken betrouwbaar te laten werken.</string> +\nVraag de beheerder van uw server om een TURN-server te configureren om gesprekken betrouwbaar te laten werken.</string> <string name="call_failed_no_connection">${app_name} Oproep Mislukt</string> - <string name="hs_client_url">Thuisserver API URL</string> - <string name="send_bug_report_include_key_share_history">Sleutel deelverzoekgeschiedenis verzenden</string> + <string name="hs_client_url">Server API URL</string> + <string name="send_bug_report_include_key_share_history">Sleutel deelverzoekgeschiedenis versturen</string> <string name="settings_room_directory_show_all_rooms_summary">Alle gesprekken in de lijst tonen, waaronder gesprekken met expliciete inhoud.</string> <string name="settings_room_directory_show_all_rooms">Gesprekken tonen met expliciete inhoud</string> <string name="settings_category_room_directory">Gesprekslijst</string> @@ -1345,11 +1312,11 @@ <string name="login_reset_password_notice">Er wordt een verificatie-e-mail naar uw inbox gestuurd om het instellen van uw nieuwe wachtwoord te bevestigen.</string> <string name="login_reset_password_on">Wachtwoord opnieuw instellen op %1$s</string> <string name="login_login_with_email_error">Dit e-mailadres is niet gekoppeld aan een account.</string> - <string name="login_registration_not_supported">De applicatie kan geen account aanmaken op deze thuisserver. + <string name="login_registration_not_supported">De applicatie kan geen account aanmaken op deze server. \n \nWilt u zich aanmelden met een webclient\?</string> <string name="login_registration_disabled">Sorry, deze server accepteert geen nieuwe accounts.</string> - <string name="login_mode_not_supported">De applicatie kan niet inloggen op deze thuisserver. De thuisserver ondersteunt de volgende aanmeldingstype(s): %1$s. + <string name="login_mode_not_supported">De applicatie kan niet inloggen op deze server. De thuisserver ondersteunt de volgende aanmeldingstype(s): %1$s. \n \nWil je inloggen met een webclient\?</string> <string name="login_sso_error_message">Er is een fout opgetreden bij het laden van de pagina: %1$s (%2$d)</string> @@ -1381,7 +1348,7 @@ <string name="room_join_rules_invite_by_you">Je hebt de kamer alleen op uitnodiging gemaakt.</string> <string name="room_join_rules_invite">%1$s heeft de kamer alleen voor uitnodigingen ingesteld.</string> <string name="room_join_rules_public_by_you">U heeft de kamer openbaar gemaakt voor iedereen die de link kent.</string> - <string name="no_ignored_users">U negeert geen enkele gebruiker</string> + <string name="no_ignored_users">U negeert geen enkele persoon</string> <string name="room_join_rules_public">%1$s heeft de kamer openbaar gemaakt voor iedereen die de link kent.</string> <string name="help_long_click_on_room_for_more_options">Klik lang op een kamer om meer opties te zien</string> <string name="reaction_search_type_hint">Schrijf trefwoorden om een reactie te vinden.</string> @@ -1395,18 +1362,17 @@ <string name="room_list_quick_actions_favorite_remove">Verwijder van favorieten</string> <string name="room_list_quick_actions_favorite_add">Toevoegen aan favorieten</string> <string name="room_list_quick_actions_notifications_all_noisy">Alle berichten (luidruchtig)</string> - <string name="content_reported_as_inappropriate_content">Deze inhoud is als ongepast gerapporteerd. \n -\nAls u geen inhoud van deze gebruiker meer wilt zien, kunt u deze negeren om hun berichten te verbergen.</string> +\nAls u geen inhoud van deze persoon meer wilt zien, kunt u deze negeren om hun berichten te verbergen.</string> <string name="content_reported_as_inappropriate_title">Gemeld als ongepast</string> <string name="content_reported_as_spam_content">Deze inhoud is gerapporteerd als spam. \n -\nAls u geen inhoud van deze gebruiker meer wilt zien, kunt u deze negeren om hun berichten te verbergen.</string> +\nAls u geen inhoud van deze persoon meer wilt zien, kunt u deze negeren om hun berichten te verbergen.</string> <string name="content_reported_as_spam_title">Gerapporteerd als spam</string> <string name="content_reported_content">Deze inhoud is gemeld. \n -\nAls u geen inhoud van deze gebruiker meer wilt zien, kunt u deze negeren om hun berichten te verbergen.</string> +\nAls u geen inhoud van deze persoon meer wilt zien, kunt u deze negeren om hun berichten te verbergen.</string> <string name="report_content_custom_hint">Reden voor het rapporteren van deze inhoud</string> <string name="report_content_custom_title">Deze inhoud rapporteren</string> <string name="uploads_files_no_result">Er zijn geen bestanden in deze kamer</string> @@ -1420,8 +1386,8 @@ <string name="error_attachment">Er is een fout opgetreden bij het ophalen van de bijlage.</string> <string name="error_file_too_big_simple">Het bestand is te groot om te uploaden.</string> <plurals name="fallback_users_read"> - <item quantity="one">%d gebruiker gelezen</item> - <item quantity="other">%d gebruikers gelezen</item> + <item quantity="one">%d persoon gelezen</item> + <item quantity="other">%d personen gelezen</item> </plurals> <string name="two_users_read">%1$s en %2$s gelezen</string> <string name="three_users_read">%1$s, %2$s en %3$s gelezen</string> @@ -1449,16 +1415,14 @@ <string name="settings_discovery_please_enter_server">Voer de URL van de identiteitsserver in</string> <string name="settings_discovery_bad_identity_server">Kan geen verbinding maken met identiteitsserver</string> <string name="settings_discovery_enter_identity_server">Voer een identiteitsserver URL in</string> - <string name="identity_server_consent_dialog_content_question">Gaat u akkoord met het verzenden van deze informatie\?</string> + <string name="identity_server_consent_dialog_content_question">Gaat u akkoord met het versturen van deze informatie\?</string> <string name="identity_server_consent_dialog_content_3">Om bestaande contacten te ontdekken, moet u contactgegevens (e-mailadressen en telefoonnummers) naar uw identiteitsserver sturen. We hashen uw gegevens voordat ze worden verzonden vanwege privacy.</string> - - <string name="identity_server_consent_dialog_title_2">Stuur e-mailadressen en telefoonnummers naar %s</string> <string name="settings_discovery_consent_action_give_consent">Toestemming geven</string> <string name="settings_discovery_consent_action_revoke">Mijn toestemming intrekken</string> - <string name="legals_home_server_title">Uw thuisserver-beleid</string> - <string name="login_error_homeserver_from_url_not_found">Kan geen thuisserver bereiken op de URL %s. Controleer uw link of kies handmatig een thuisserver.</string> - <string name="settings_discovery_consent_notice_off_2">Uw contacten zijn privé. Om gebruikers van uw contacten te ontdekken, hebben we uw toestemming nodig om contactgegevens naar uw identiteitsserver te sturen.</string> + <string name="legals_home_server_title">Uw server-beleid</string> + <string name="login_error_homeserver_from_url_not_found">Kan geen server bereiken op de URL %s. Controleer uw link of kies handmatig een server.</string> + <string name="settings_discovery_consent_notice_off_2">Uw contacten zijn privé. Om personen van uw contacten te ontdekken, hebben we uw toestemming nodig om contactgegevens naar uw identiteitsserver te sturen.</string> <string name="settings_discovery_confirm_mail_not_clicked">We hebben u een bevestigingsmail gestuurd naar %s, controleer eerst uw e-mail en klik op de bevestigingslink</string> <string name="settings_discovery_confirm_mail">We hebben u een bevestigingsmail gestuurd naar %s, controleer uw e-mail en klik op de bevestigingslink</string> <string name="settings_discovery_no_mails">Ontdekkingsopties verschijnen zodra u een e-mail heeft toegevoegd.</string> @@ -1471,14 +1435,14 @@ <string name="command_description_nick_for_room">Verander uw schermnaam alleen in de huidige kamer</string> <string name="other_spaces_or_rooms_you_might_not_know">Andere spaces of kamers die u misschien niet kent</string> <string name="space_you_know_that_contains_this_room">Space die u kent die deze kamer bevat</string> - <string name="room_alias_local_address_subtitle">Stel adressen in voor deze kamer zodat gebruikers deze kamer kunnen vinden via uw thuisserver (%1$s)</string> + <string name="room_alias_local_address_subtitle">Stel adressen in voor deze kamer zodat personen deze kamer kunnen vinden via uw server (%1$s)</string> <string name="analytics_opt_in_list_item_3">U kunt dit op elk moment uitschakelen in de instellingen</string> <string name="settings_mentions_and_keywords_encryption_notice">U krijgt geen meldingen voor vermeldingen en trefwoorden in versleutelde kamers op uw mobiel.</string> <string name="error_threepid_auth_failed">Zorg ervoor dat u op de link heeft geklikt in de e-mail die we u hebben gestuurd.</string> - <string name="settings_discovery_consent_notice_on">U hebt uw toestemming gegeven om e-mails en telefoonnummers naar deze identiteitsserver te sturen om andere gebruikers van uw contacten te ontdekken.</string> - <string name="settings_discovery_consent_title">E-mails en telefoonnummers verzenden</string> + <string name="settings_discovery_consent_notice_on">U hebt uw toestemming gegeven om e-mails en telefoonnummers naar deze identiteitsserver te sturen om andere personen van uw contacten te ontdekken.</string> + <string name="settings_discovery_consent_title">E-mailadressen en telefoonnummers versturen</string> <string name="settings_discovery_msisdn_title">Vindbare telefoonnummers</string> - <string name="settings_discovery_disconnect_identity_server_info">Als u de verbinding met uw identiteitsserver verbreekt, betekent dit dat u niet door andere gebruikers kan worden gevonden en dat u anderen niet per e-mail of telefoon kunt uitnodigen.</string> + <string name="settings_discovery_disconnect_identity_server_info">Als u de verbinding met uw identiteitsserver verbreekt, betekent dit dat u niet door andere personen kan worden gevonden en dat u anderen niet per e-mail of telefoon kunt uitnodigen.</string> <string name="settings_discovery_no_msisdn">Ontdekkingsopties verschijnen zodra u een telefoonnummer heeft toegevoegd.</string> <string name="settings_discovery_emails_title">Vindbare e-mailadressen</string> <string name="settings_discovery_identity_server_info_none">U gebruikt momenteel geen identiteitsserver. Om te ontdekken en vindbaar te zijn door bestaande contacten die u kent, configureert u er een hieronder.</string> @@ -1493,7 +1457,7 @@ <string name="terms_description_for_identity_server">Vindbaar zijn voor anderen</string> <string name="terms_of_service">Servicevoorwaarden</string> <string name="message_view_edit_history">Bekijken Bewerken Geschiedenis</string> - <string name="direct_room_user_list_known_title">Bekende gebruikers</string> + <string name="direct_room_user_list_known_title">Bekende personen</string> <string name="qr_code">QR-code</string> <string name="add_by_qr_code">Toevoegen via QR-code</string> <string name="link_copied_to_clipboard">Link gekopieerd naar klembord</string> @@ -1503,22 +1467,22 @@ <string name="user_directory_search_hint_2">Zoeken op naam, ID of e-mail</string> <string name="room_directory_search_hint">Naam of ID (#voorbeeld:matrix.org)</string> <string name="room_filtering_footer_open_room_directory">Bekijk de kamer directory</string> - <string name="room_filtering_footer_create_new_direct_message">Een nieuw privébericht verzenden</string> + <string name="room_filtering_footer_create_new_direct_message">Een nieuw privébericht versturen</string> <string name="room_filtering_footer_create_new_room">Nieuwe kamer aanmaken</string> <string name="room_filtering_footer_title">Kunt u niet vinden wat u zoekt\?</string> <string name="no_message_edits_found">Geen bewerkingen gevonden</string> <string name="downloaded_file">Bestand %1$s is gedownload!</string> <string name="send_file_step_compressing_video">Video comprimeren %d%%</string> <string name="send_file_step_compressing_image">Afbeelding comprimeren…</string> - <string name="send_file_step_sending_file">Bestand verzenden (%1$s / %2$s)</string> - <string name="send_file_step_sending_thumbnail">Miniatuur verzenden (%1$s / %2$s)</string> + <string name="send_file_step_sending_file">Bestand versturen (%1$s / %2$s)</string> + <string name="send_file_step_sending_thumbnail">Miniatuur versturen (%1$s / %2$s)</string> <string name="settings_labs_show_complete_history_in_encrypted_room">Toon volledige geschiedenis in versleutelde kamers</string> <string name="settings_labs_show_hidden_events_in_timeline">Toon verborgen gebeurtenissen op de tijdlijn</string> <string name="give_feedback">Geef feedback</string> <string name="feedback_failed">De feedback kan niet worden verzonden (%s)</string> <string name="feedback_sent">Bedankt, uw feedback is succesvol verzonden</string> <string name="you_may_contact_me">U kunt contact met mij opnemen als u vervolgvragen heeft</string> - <string name="send_feedback_space_info">U gebruikt een bètaversie van spaces. Uw feedback zal helpen bij het informeren van de volgende versies. Uw platform en gebruikersnaam worden genoteerd om ons te helpen uw feedback zoveel mogelijk te gebruiken.</string> + <string name="send_feedback_space_info">U gebruikt een bètaversie van spaces. Uw feedback zal helpen bij het informeren van de volgende versies. Uw platform en inlognaam worden genoteerd om ons te helpen uw feedback zoveel mogelijk te gebruiken.</string> <string name="send_feedback_space_title">Spaces feedback</string> <string name="send_suggestion_failed">De suggestie kan niet worden verzonden (%s)</string> <string name="send_suggestion_sent">Bedankt, de suggestie is succesvol verzonden</string> @@ -1551,11 +1515,11 @@ <string name="secure_backup_setup">Beveiligde back-up instellen</string> <string name="secure_backup_banner_setup_line2">Beveiliging tegen verlies van toegang tot versleutelde berichten en gegevens</string> <string name="recovery_key_export_saved">De herstelsleutel is opgeslagen.</string> - <string name="command_description_whois">Toont informatie over een gebruiker</string> + <string name="command_description_whois">Toont informatie over een persoon</string> <string name="command_description_room_avatar">Verandert de avatar van de huidige kamer</string> <string name="command_description_room_name">Stelt de kamernaam in</string> - <string name="command_description_unignore_user">Stopt met het negeren van een gebruiker, toon hun berichten in de toekomst</string> - <string name="command_description_ignore_user">Negeer een gebruiker en verberg hun berichten voor jou</string> + <string name="command_description_unignore_user">Stopt met het negeren van een persoon, toon hun berichten in de toekomst</string> + <string name="command_description_ignore_user">Negeer een persoon en verberg hun berichten voor jou</string> <string name="room_no_active_widgets">Geen actieve widgets</string> <string name="jitsi_leave_conf_to_join_another_one_content">De huidige conferentie verlaten en naar de andere overschakelen\?</string> <string name="error_jitsi_join_conf">Sorry, er is een fout opgetreden bij het deelnemen aan de conferentie</string> @@ -1574,8 +1538,8 @@ <string name="encryption_exported_successfully">Sleutels succesvol geëxporteerd</string> <string name="room_settings_room_version_title">Kamer versie</string> <plurals name="room_settings_banned_users_count"> - <item quantity="one">%d verbannen gebruiker</item> - <item quantity="other">%d verbannen gebruikers</item> + <item quantity="one">%d verbannen persoon</item> + <item quantity="other">%d verbannen personen</item> </plurals> <string name="decide_who_can_find_and_join">Bepaal wie deze kamer kan vinden en er lid van kan worden.</string> <string name="tap_to_edit_spaces">Tik om spaces te bewerken</string> @@ -1654,7 +1618,7 @@ <string name="settings_group_messages">Groepsberichten</string> <string name="settings_encrypted_direct_messages">Versleutelde directe berichten</string> <string name="settings_messages_direct_messages">Directe berichten</string> - <string name="settings_messages_containing_username">Mijn gebruikersnaam</string> + <string name="settings_messages_containing_username">Mijn inlognaam</string> <string name="settings_messages_containing_display_name">Mijn weergavenaam</string> <string name="settings_messages_at_room">Berichten bevatten @room</string> <string name="settings_when_rooms_are_upgraded">Wanneer kamers worden opgewaardeerd</string> @@ -1681,7 +1645,7 @@ <string name="shortcut_disabled_reason_sign_out">De sessie is afgemeld!</string> <string name="shortcut_disabled_reason_room_left">De kamer is verlaten!</string> <string name="room_settings_mention_and_keyword_only">Alleen vermeldingen en trefwoorden</string> - <string name="search_banned_user_hint">Filter verbannen gebruikers</string> + <string name="search_banned_user_hint">Filter verbannen personen</string> <string name="room_permissions_change_topic">Verander onderwerp</string> <string name="room_permissions_upgrade_the_space">Space upgraden</string> <string name="room_permissions_upgrade_the_room">Kamer upgraden</string> @@ -1699,10 +1663,10 @@ <string name="room_permissions_modify_widgets">Widgets wijzigen</string> <string name="room_permissions_notify_everyone">Iedereen informeren</string> <string name="room_permissions_remove_messages_sent_by_others">Berichten verwijderen die door anderen zijn verzonden</string> - <string name="room_permissions_ban_users">Gebruikers verbannen</string> - <string name="room_permissions_remove_users">Kick gebruikers</string> + <string name="room_permissions_ban_users">Personen verbannen</string> + <string name="room_permissions_remove_users">Kick personen</string> <string name="room_permissions_change_settings">Instellingen veranderen</string> - <string name="room_permissions_invite_users">Gebruikers uitnodigen</string> + <string name="room_permissions_invite_users">Personen uitnodigen</string> <string name="room_permissions_send_messages">Berichten sturen</string> <string name="room_permissions_default_role">Standaardrol</string> <string name="space_permissions_notice_read_only">U bent niet gemachtigd om de rollen bij te werken die nodig zijn om verschillende delen van deze space te wijzigen</string> @@ -1711,7 +1675,7 @@ <string name="room_permissions_notice">Selecteer de rollen die nodig zijn om verschillende delen van de kamer te veranderen</string> <string name="space_settings_permissions_subtitle">Bekijk en update de rollen die nodig zijn om verschillende delen van de kamer te veranderen.</string> <string name="room_settings_permissions_subtitle">Bekijk en update de rollen die nodig zijn om verschillende delen van de kamer te veranderen.</string> - <string name="login_error_homeserver_from_url_not_found_enter_manual">Kies thuisserver</string> + <string name="login_error_homeserver_from_url_not_found_enter_manual">Kies server</string> <string name="action_not_now">Niet nu</string> <string name="action_enable">Inschakelen</string> <string name="notification_listening_for_notifications">Luisteren naar notificaties</string> @@ -1723,12 +1687,12 @@ <string name="dev_tools_error_no_content">Geen content</string> <string name="dev_tools_form_hint_event_content">Event inhoud</string> <string name="dev_tools_form_hint_state_key">Statussleutel</string> - <string name="dev_tools_send_custom_state_event">Aangepaste statusgebeurtenis verzenden</string> + <string name="dev_tools_send_custom_state_event">Aangepaste statusgebeurtenis versturen</string> <string name="dev_tools_edit_content">Inhoud bewerken</string> <string name="dev_tools_state_event">Staat gebeurtenissen</string> - <string name="dev_tools_send_state_event">Statusgebeurtenis verzenden</string> - <string name="dev_tools_send_custom_event">Aangepaste gebeurtenis verzenden</string> - <string name="dev_tools_explore_room_state">Kamerstatus verkennen</string> + <string name="dev_tools_send_state_event">Statusgebeurtenis versturen</string> + <string name="dev_tools_send_custom_event">Aangepaste gebeurtenis versturen</string> + <string name="dev_tools_explore_room_state">Kamer status ontdekken</string> <string name="dev_tools_menu_name">Ontwikkel tools</string> <string name="a11y_presence_unavailable">Niet beschikbaar</string> <string name="a11y_presence_offline">Offline</string> @@ -1765,8 +1729,6 @@ <item quantity="one">Actieve oproep ·</item> <item quantity="other">%1$d actieve gesprekken ·</item> </plurals> - - <string name="call_only_active">Actieve oproep (%1$s)</string> <string name="call_dial_pad_lookup_error">Er is een fout opgetreden bij het opzoeken van het telefoonnummer</string> <string name="call_dial_pad_title">Toetsenblok</string> @@ -1827,7 +1789,7 @@ </plurals> <string name="alert_push_are_disabled_description">Controleer uw instellingen om pushmeldingen in te schakelen</string> <string name="alert_push_are_disabled_title">Pushmeldingen zijn uitgeschakeld</string> - <string name="failed_to_unban">Kan gebruiker verbanning niet opheffen</string> + <string name="failed_to_unban">Kan persoon verbanning niet opheffen</string> <string name="member_banned_by">Verbannen door %1$s</string> <string name="three_pid_revoke_invite_dialog_content">Uitnodiging voor %1$s intrekken\?</string> <string name="phone_book_perform_lookup">Zoeken naar contacten op Matrix</string> @@ -1863,14 +1825,14 @@ <string name="a11y_mute_microphone">De microfoon dempen</string> <string name="identity_server_set_alternative_notice_no_default">Voer de URL van een identiteitsserver in</string> <string name="identity_server_set_alternative_notice">U kunt ook een andere identiteitsserver URL invoeren</string> - <string name="identity_server_set_default_notice">Uw thuisserver (%1$s) stelt voor om %2$s te gebruiken voor uw identiteitsserver</string> - <string name="identity_server_user_consent_not_provided">De toestemming van de gebruiker is niet gegeven.</string> + <string name="identity_server_set_default_notice">Uw server (%1$s) stelt voor om %2$s te gebruiken voor uw identiteitsserver</string> + <string name="identity_server_user_consent_not_provided">De toestemming van de persoon is niet gegeven.</string> <string name="identity_server_error_no_current_binding_error">Er is geen huidige associatie met dit id.</string> <string name="identity_server_error_binding_error">De associatie heeft gefaald.</string> - <string name="identity_server_error_bulk_sha256_not_supported">Voor uw privacy ondersteunt ${app_name} alleen het verzenden van gehashte e-mailadressen en telefoonnummers van gebruikers.</string> + <string name="identity_server_error_bulk_sha256_not_supported">Voor uw privacy ondersteunt ${app_name} alleen het versturen van gehashte e-mailadressen en telefoonnummers van personen.</string> <string name="identity_server_error_terms_not_signed">Accepteer eerst de voorwaarden van de identiteitsserver in de instellingen.</string> <string name="identity_server_error_no_identity_server_configured">Configureer eerst een identiteitsserver.</string> - <string name="identity_server_error_outdated_home_server">Deze operatie is niet mogelijk. De thuisserver is verouderd.</string> + <string name="identity_server_error_outdated_home_server">Deze operatie is niet mogelijk. De server is verouderd.</string> <string name="identity_server_error_outdated_identity_server">Deze identiteitsserver is verouderd. ${app_name} ondersteunt alleen API V2.</string> <string name="disconnect_identity_server_dialog_content">Verbinding met identiteitsserver %s verbreken\?</string> <string name="open_terms_of">Open voorwaarden van %s</string> @@ -1880,7 +1842,7 @@ <string name="user_code_my_code">Mijn code</string> <string name="user_code_share">Deel mijn code</string> <string name="user_code_scan">Scan een QR-code</string> - <string name="invite_users_to_room_failure">We kunnen geen gebruikers uitnodigen. Controleer de gebruikers die u wilt uitnodigen en probeer het opnieuw.</string> + <string name="invite_users_to_room_failure">We kunnen geen personen uitnodigen. Controleer de personen die u wilt uitnodigen en probeer het opnieuw.</string> <plurals name="invitations_sent_to_one_and_more_users"> <item quantity="one">Uitnodigingen verzonden naar %1$s en nog één</item> <item quantity="other">Uitnodigingen verzonden naar %1$s en %2$d meer</item> @@ -1892,13 +1854,13 @@ <string name="invite_friends_text">Hé, praat met me op ${app_name}: %s</string> <string name="invite_friends">Nodig vrienden uit</string> <string name="add_people">Mensen toevoegen</string> - <string name="create_room_dm_failure">We kunnen je DM niet maken. Controleer de gebruikers die u wilt uitnodigen en probeer het opnieuw.</string> + <string name="create_room_dm_failure">We kunnen je DM niet maken. Controleer de personen die u wilt uitnodigen en probeer het opnieuw.</string> <string name="external_link_confirmation_message">De link %1$s brengt u naar een andere site: %2$s. \n \nWeet u zeker dat u door wilt gaan\?</string> <string name="external_link_confirmation_title">Dubbelcheck deze link</string> <string name="error_empty_field_choose_password">Kies een wachtwoord.</string> - <string name="error_empty_field_choose_user_name">Kies een gebruikersnaam.</string> + <string name="error_empty_field_choose_user_name">Kies een inlognaam.</string> <string name="failed_to_initialize_cross_signing">Kan kruislingsondertekenen niet instellen</string> <string name="confirm_your_identity_quad_s">Bevestig uw identiteit door deze login te verifiëren en deze toegang te verlenen tot versleutelde berichten.</string> <string name="confirm_your_identity">Bevestig uw identiteit door deze login van een van uw andere sessies te verifiëren en toegang te verlenen tot versleutelde berichten.</string> @@ -1916,7 +1878,7 @@ <item quantity="one">Laat het apparaat zien waarmee u nu kunt verifiëren</item> <item quantity="other">%d apparaten weergeven waarmee u nu kunt verifiëren</item> </plurals> - <string name="secure_backup_reset_no_history">U start opnieuw op zonder geschiedenis, geen berichten, vertrouwde apparaten of vertrouwde gebruikers</string> + <string name="secure_backup_reset_no_history">U start opnieuw op zonder geschiedenis, geen berichten, vertrouwde apparaten of vertrouwde personen</string> <string name="secure_backup_reset_if_you_reset_all">Als je alles reset</string> <string name="secure_backup_reset_all_no_other_devices">Doe dit alleen als u geen ander apparaat heeft waarmee u dit apparaat kunt verifiëren.</string> <string name="bad_passphrase_key_reset_all_action">Alle herstelopties vergeten of verloren\? Alles resetten</string> @@ -1954,7 +1916,7 @@ <string name="security_prompt_text">Verifieer uzelf en anderen om uw chats veilig te houden</string> <string name="upgrade_security">Encryptie upgrade beschikbaar</string> <string name="auth_invalid_login_deactivated_account">Dit account is gedeactiveerd.</string> - <string name="auth_invalid_login_param_space_in_password">Onjuiste gebruikersnaam en/of wachtwoord. Het ingevoerde wachtwoord begint of eindigt met spaties, controleer dit alstublieft.</string> + <string name="auth_invalid_login_param_space_in_password">Onjuiste inlognaam en/of wachtwoord. Het ingevoerde wachtwoord begint of eindigt met spaties, controleer dit alstublieft.</string> <string name="command_description_plain">Verzendt een bericht als platte tekst, zonder het als markdown te interpreteren</string> <string name="error_failed_to_import_keys">Kan sleutels niet importeren</string> <string name="qr_code_scanned_verif_waiting">Wachten op %s…</string> @@ -1970,11 +1932,10 @@ <string name="encryption_unknown_algorithm_tile_description">De versleuteling die door deze kamer wordt gebruikt, wordt niet ondersteund</string> <string name="encryption_not_enabled">Versleuteling niet ingeschakeld</string> <string name="direct_room_encryption_enabled_tile_description">Berichten in deze kamer zijn end-to-end-versleuteld.</string> - <string name="encryption_enabled_tile_description">Berichten in deze kamer zijn end-to-end-versleuteld. Lees meer en verifieer gebruikers in hun profiel.</string> + <string name="encryption_enabled_tile_description">Berichten in deze kamer zijn eind-tot-eind-versleuteld. Lees meer en verifieer persoon in hun profiel.</string> <string name="bootstrap_cancel_text">Als u nu annuleert, kunt u versleutelde berichten en gegevens kwijtraken als u de toegang tot uw aanmeldingen verliest. \n \nU kunt ook Veilige back-up instellen en uw sleutels beheren in Instellingen.</string> - <string name="bootstrap_crosssigning_save_cloud">Kopieer het naar uw persoonlijke cloudopslag</string> <string name="bootstrap_crosssigning_save_usb">Bewaar het op een USB-stick of back-upstation</string> <string name="bootstrap_crosssigning_print_it">Print het uit en bewaar het ergens veilig</string> @@ -1983,7 +1944,7 @@ \nHoud ze veilig! U heeft ze nodig om versleutelde berichten te ontgrendelen en informatie te beveiligen als u al uw actieve sessies verliest.</string> <string name="bootstrap_crosssigning_progress_key_backup">Sleutelback-up instellen</string> <string name="bootstrap_crosssigning_progress_save_ssk">Zelfondertekenende sleutel synchroniseren</string> - <string name="bootstrap_crosssigning_progress_save_usk">Gebruikerssleutel synchroniseren</string> + <string name="bootstrap_crosssigning_progress_save_usk">Persoonssleutel synchroniseren</string> <string name="bootstrap_crosssigning_progress_save_msk">Hoofdsleutel synchroniseren</string> <string name="bootstrap_crosssigning_progress_default_key">SSSS standaardsleutel definiëren</string> <string name="bootstrap_crosssigning_progress_pbkdf2">Beveiligde sleutel genereren op basis van wachtwoordzin</string> @@ -1998,14 +1959,14 @@ <string name="verify_not_me_self_verification">Een van de volgende zaken kan worden aangetast: \n \n- Uw wachtwoord -\n- Uw thuisserver +\n- Uw server \n- Dit apparaat, of het andere apparaat \n- De internetverbinding die elk apparaat gebruikt \n \nWe raden u aan uw wachtwoord en herstelsleutel onmiddellijk in Instellingen te wijzigen.</string> - <string name="verify_cancel_other">U verifieert %1$s (%2$s) niet als u nu annuleert. Begin opnieuw in hun gebruikersprofiel.</string> - <string name="verify_cancel_self_verification_from_untrusted">Als u annuleert, kunt u geen versleutelde berichten op dit apparaat lezen en zullen andere gebruikers het niet vertrouwen</string> - <string name="verify_cancel_self_verification_from_trusted">Als u annuleert, kunt u geen versleutelde berichten lezen op je nieuwe apparaat en zullen andere gebruikers het niet vertrouwen</string> + <string name="verify_cancel_other">U verifieert %1$s (%2$s) niet als u nu annuleert. Begin opnieuw in hun profiel.</string> + <string name="verify_cancel_self_verification_from_untrusted">Als u annuleert, kunt u geen versleutelde berichten op dit apparaat lezen en zullen andere personen het niet vertrouwen</string> + <string name="verify_cancel_self_verification_from_trusted">Als u annuleert, kunt u geen versleutelde berichten lezen op je nieuwe apparaat en zullen andere personen het niet vertrouwen</string> <string name="verify_new_session_compromized">Uw account is mogelijk gecompromitteerd</string> <string name="verify_new_session_was_not_me">Dit was ik niet</string> <string name="verify_new_session_notice">Gebruik deze sessie om uw nieuwe te verifiëren en deze toegang te verlenen tot versleutelde berichten.</string> @@ -2015,11 +1976,11 @@ <string name="login_default_session_public_name">${app_name} Android</string> <string name="keys_backup_restore_success_title_already_up_to_date">Sleutels zijn al up-to-date!</string> <string name="event_redacted_by_admin_reason_with_reason">Gebeurtenis gemodereerd door kamer beheerder, reden: %1$s</string> - <string name="event_redacted_by_user_reason_with_reason">Gebeurtenis verwijderd door gebruiker, reden: %1$s</string> + <string name="event_redacted_by_user_reason_with_reason">Gebeurtenis verwijderd door persoon, reden: %1$s</string> <string name="delete_event_dialog_reason_hint">Reden voor redigeren</string> <string name="delete_event_dialog_reason_checkbox">Geef een reden op</string> <string name="delete_event_dialog_content">Weet u zeker dat u deze gebeurtenis wilt verwijderen (wissen)\? Houd er rekening mee dat als u een kamer naam of onderwerpwijziging verwijdert, de wijziging ongedaan kan worden gemaakt.</string> - <string name="send_images_and_video_with_original_size">Media verzenden in het originele formaat</string> + <string name="send_images_and_video_with_original_size">Media versturen in het originele formaat</string> <plurals name="send_videos_with_original_size"> <item quantity="one">Stuur video in het originele formaat</item> <item quantity="other">Stuur video\'s in het originele formaat</item> @@ -2038,7 +1999,7 @@ <string name="no_connectivity_to_the_server_indicator_airplane">Vliegtuigmodus is ingeschakeld</string> <string name="no_connectivity_to_the_server_indicator">Verbinding met de server is verbroken</string> <string name="qr_code_scanned_by_other_notice">Bijna daar! Toont %s een vinkje\?</string> - <string name="verification_profile_device_untrust_info">Totdat deze gebruiker deze sessie vertrouwt, worden berichten die van en naar de sessie worden verzonden, gelabeld met waarschuwingen. U kunt het ook handmatig verifiëren.</string> + <string name="verification_profile_device_untrust_info">Totdat deze persoon deze sessie vertrouwt, worden berichten die van en naar de sessie worden verzonden, gelabeld met waarschuwingen. U kunt het ook handmatig verifiëren.</string> <string name="verification_profile_device_new_signing">%1$s (%2$s) aangemeld met een nieuwe sessie:</string> <string name="verification_profile_device_verified_because">Deze sessie wordt vertrouwd voor veilig berichtenverkeer omdat %1$s (%2$s) deze heeft geverifieerd:</string> <string name="room_member_profile_failed_to_get_devices">Kan geen sessies ophalen</string> @@ -2054,7 +2015,7 @@ <string name="settings_server_default_room_version">Standaardversie</string> <string name="settings_server_room_versions">Kamerversies 👓</string> <string name="settings_server_upload_size_unknown">De limiet is onbekend.</string> - <string name="settings_server_upload_size_content">Uw thuisserver accepteert bijlagen (bestanden, media, enz.) met een grootte tot %s.</string> + <string name="settings_server_upload_size_content">Uw server accepteert bijlagen (bestanden, media, enz.) met een grootte tot %s.</string> <string name="settings_server_upload_size_title">Server limiet voor het uploaden van bestanden</string> <string name="settings_server_version">Serverversie</string> <string name="settings_server_name">Server naam</string> @@ -2069,9 +2030,9 @@ \nPrivésleutels zijn niet bekend</string> <string name="encryption_information_dg_xsigning_complete">Kruisondertekening is ingeschakeld \nPrivésleutels op het apparaat.</string> - <string name="verification_conclusion_ok_self_notice">Uw nieuwe sessie is nu geverifieerd. Het heeft toegang tot uw gecodeerde berichten en andere gebruikers zullen het als vertrouwd zien.</string> - <string name="verification_conclusion_ok_notice">Berichten met deze gebruiker zijn end-to-end-versleuteld en kunnen niet door derden worden gelezen.</string> - <string name="verification_code_notice">Vergelijk de code met die op het scherm van de andere gebruiker.</string> + <string name="verification_conclusion_ok_self_notice">Uw nieuwe sessie is nu geverifieerd. Het heeft toegang tot uw gecodeerde berichten en andere personen zullen het als vertrouwd zien.</string> + <string name="verification_conclusion_ok_notice">Berichten met deze persoon zijn end-to-end-versleuteld en kunnen niet door derden worden gelezen.</string> + <string name="verification_code_notice">Vergelijk de code met die op het scherm van de andere persoon.</string> <string name="verification_emoji_notice">Vergelijk de unieke emoji en zorg ervoor dat ze in dezelfde volgorde verschijnen.</string> <string name="verification_request_start_notice">Doe dit voor de zekerheid persoonlijk of gebruik een andere manier om te communiceren.</string> <string name="verification_request_notice">Om veilig te zijn, verifieert u %s door een eenmalige code te controleren.</string> @@ -2099,7 +2060,6 @@ \nUw berichten zijn beveiligd met sloten en alleen u en de ontvanger hebben de unieke sleutels om ze te ontgrendelen.</string> <string name="direct_room_profile_not_encrypted_subtitle">Berichten hier zijn niet end-to-end-versleuteld.</string> <string name="room_profile_not_encrypted_subtitle">Berichten in deze kamer zijn niet end-to-end-versleuteld.</string> - <string name="verification_request_waiting_for">Wachten op %s…</string> <string name="verification_no_scan_emoji_title">Verifieer door emoji\'s te vergelijken</string> <string name="verification_scan_self_emoji_subtitle">Verifieer door emoji te vergelijken</string> @@ -2107,15 +2067,15 @@ <string name="verification_scan_with_this_device">Scannen met dit apparaat</string> <string name="verification_scan_their_code">Scan hun code</string> <string name="verification_scan_self_notice">Scan de code met uw ander apparaat of wissel en scan met dit apparaat</string> - <string name="verification_scan_notice">Scan de code met het apparaat van de andere gebruiker om elkaar veilig te verifiëren</string> + <string name="verification_scan_notice">Scan de code met het apparaat van de andere persoon om elkaar veilig te verifiëren</string> <string name="verification_verify_device">Deze sessie verifiëren</string> <string name="sent_a_reaction">Gereageerd met: %s</string> <string name="verification_conclusion_compromised">"Een van de volgende zaken kan worden aangetast: \n -\n - Uw thuisserver -\n - De thuisserver waarmee de gebruiker die u verifieert is verbonden -\n - De internetverbinding van u of de andere gebruikers -\n - Het apparaat van u of van andere gebruikers"</string> +\n - Uw server +\n - De server waarmee de gebruiker die u verifieert is verbonden +\n - De internetverbinding van u of de andere personen +\n - Het apparaat van u of van andere personen"</string> <string name="verification_sas_do_not_match">Ze komen niet overeen</string> <string name="verification_conclusion_warning">Niet-vertrouwd inloggen</string> <string name="login_error_threepid_denied">Uw e-maildomein is niet geautoriseerd om op deze server te registreren</string> @@ -2125,7 +2085,7 @@ <string name="create_room_alias_empty">Geef een kameradres op</string> <string name="create_room_alias_already_in_use">Dit adres is al in gebruik</string> <string name="create_space_alias_hint">Space adres</string> - <string name="create_room_disable_federation_description">U kunt dit inschakelen als de kamer alleen wordt gebruikt voor samenwerking met interne teams op uw thuisserver. Dit kan later niet meer worden gewijzigd.</string> + <string name="create_room_disable_federation_description">U kunt dit inschakelen als de kamer alleen wordt gebruikt voor samenwerking met interne teams op uw server. Dit kan later niet meer worden gewijzigd.</string> <string name="create_room_disable_federation_title">Blokkeer iedereen die geen deel uitmaakt van %s om ooit deel te nemen aan deze kamer</string> <string name="hide_advanced">Verberg geavanceerd</string> <string name="show_advanced">Toon geavanceerd</string> @@ -2140,7 +2100,7 @@ <string name="settings_developer_mode_summary">De ontwikkelaarsmodus activeert verborgen functies en kan de applicatie ook minder stabiel maken. Alleen voor ontwikkelaars!</string> <string name="bug_report_error_too_short">De beschrijving is te kort</string> <string name="permalink_malformed">Uw matrix.to link is onjuist opgemaakt</string> - <string name="soft_logout_sso_not_same_user_error">De huidige sessie is voor gebruiker %1$s en u geeft inloggegevens op voor gebruiker %2$s. Dit wordt niet ondersteund door ${app_name}. + <string name="soft_logout_sso_not_same_user_error">De huidige sessie is voor gebruiker %1$s en u geeft inloggegevens op voor persoon %2$s. Dit wordt niet ondersteund door ${app_name}. \nWis eerst de gegevens en meld u vervolgens opnieuw aan met een ander account.</string> <string name="soft_logout_clear_data_dialog_e2e_warning_content">U raakt de toegang tot beveiligde berichten kwijt, tenzij u zich aanmeldt om uw versleutelingssleutels te herstellen.</string> <string name="soft_logout_clear_data_dialog_content">Alle gegevens wissen die momenteel op dit apparaat zijn opgeslagen\? @@ -2151,7 +2111,7 @@ \nWis het als u klaar bent met het gebruik van dit apparaat of als u zich wilt aanmelden bij een ander account.</string> <string name="soft_logout_clear_data_title">Persoonlijke gegevens wissen</string> <string name="soft_logout_signin_e2e_warning_notice">Log in om versleutelingssleutels te herstellen die exclusief op dit apparaat zijn opgeslagen. Je hebt ze nodig om al uw beveiligde berichten op elk apparaat te lezen.</string> - <string name="soft_logout_signin_notice">Uw thuisserver (%1$s) beheerder heeft u uitgelogd van uw account %2$s (%3$s).</string> + <string name="soft_logout_signin_notice">Uw server (%1$s) beheerder heeft u uitgelogd van uw account %2$s (%3$s).</string> <string name="soft_logout_title">Je bent uitgelogd</string> <string name="signed_out_submit">Opnieuw inloggen</string> <string name="signed_out_notice">Het kan verschillende redenen hebben: @@ -2162,30 +2122,30 @@ \n \n• De beheerder van uw server heeft uw toegang om veiligheidsredenen ongeldig gemaakt.</string> <string name="signed_out_title">Je bent uitgelogd</string> - <string name="autodiscover_well_known_error">Kan geen geldige thuisserver vinden. Controleer uw ID a.u.b.</string> - <string name="login_signin_matrix_id_error_invalid_matrix_id">Dit is geen geldige gebruikers-ID. Verwacht formaat: \'@gebruiker:thuisserver.org\'</string> + <string name="autodiscover_well_known_error">Kan geen geldige server vinden. Controleer uw ID a.u.b.</string> + <string name="login_signin_matrix_id_error_invalid_matrix_id">Dit is geen geldige persoon-ID. Verwacht formaat: \'@persoon:server.org\'</string> <string name="login_signin_matrix_id_password_notice">Als u uw wachtwoord niet weet, gaat u terug om het opnieuw in te stellen.</string> - <string name="login_signin_matrix_id_notice">Als je een account aanmaakt op een thuisserver, gebruik dan je Matrix ID (bijv. @gebruiker:domein.nl) en wachtwoord hieronder.</string> + <string name="login_signin_matrix_id_notice">Als je een account aanmaakt op een server, gebruik dan je Matrix ID (bijv. @persoon:domein.nl) en wachtwoord hieronder.</string> <string name="login_signin_matrix_id_title">Aanmelden met Matrix ID</string> <string name="login_connect_using_matrix_id_submit">Aanmelden met Matrix ID</string> <plurals name="login_error_limit_exceeded_retry_after"> <item quantity="one">Er zijn te veel verzoeken verzonden. Je kunt het over %1$d seconde opnieuw proberen…</item> <item quantity="other">Er zijn te veel verzoeken verzonden. Je kunt het over %1$d seconden opnieuw proberen…</item> </plurals> - <string name="login_error_outdated_homeserver_warning_content">Deze thuisserver draait op een oude versie. Vraag uw thuisserver beheerder om te upgraden. U kunt doorgaan, maar sommige functies werken mogelijk niet correct.</string> + <string name="login_error_outdated_homeserver_warning_content">Deze server draait op een oude versie. Vraag uw server beheerder om te upgraden. U kunt doorgaan, maar sommige functies werken mogelijk niet correct.</string> <string name="login_validation_code_is_not_correct">De ingevoerde code is niet correct. Gelieve dit te controleren.</string> <string name="login_wait_for_email_notice">We hebben zojuist een e-mail gestuurd naar %1$s. \nKlik op de link die deze bevat om door te gaan met het aanmaken van een account.</string> <string name="login_wait_for_email_title">Controleer uw e-mail</string> <string name="login_terms_title">Accepteer de voorwaarden om door te gaan</string> <string name="login_a11y_captcha_container">Voer de captcha uitdaging uit</string> - <string name="login_a11y_choose_other">Selecteer een aangepaste thuisserver</string> + <string name="login_a11y_choose_other">Selecteer een aangepaste server</string> <string name="login_a11y_choose_modular">Selecteer Element Matrix Services</string> <string name="login_signup_cancel_confirmation_content">Uw account is nog niet aangemaakt. \n \nHet registratieproces stoppen\?</string> - <string name="login_signup_error_user_in_use">Die gebruikersnaam is in gebruik</string> - <string name="login_signin_username_hint">Gebruikersnaam of e-mail</string> + <string name="login_signup_error_user_in_use">Deze inlognaam is in gebruik</string> + <string name="login_signin_username_hint">Inlognaam of e-mailadres</string> <string name="login_signup_to">Meld u aan bij %1$s</string> <string name="login_msisdn_error_other">Telefoonnummer lijkt ongeldig. Controleer het alstublieft</string> <string name="login_msisdn_error_not_international">Internationale telefoonnummers moeten beginnen met \'+\'</string> @@ -2216,7 +2176,6 @@ <string name="upgrade_room_for_restricted_no_param">Iedereen in een ouderkamer kan deze kamer vinden en er lid van worden. Het is niet nodig om iedereen handmatig uit te nodigen. U kunt dit op elk moment wijzigen in de kamer instellingen.</string> <string name="upgrade_room_warning">Het upgraden van een kamer is een geavanceerde actie en wordt meestal aanbevolen wanneer een kamer onstabiel is vanwege bugs, ontbrekende functies of beveiligingsproblemen. \nDit heeft meestal alleen invloed op hoe de kamer op de server wordt verwerkt.</string> - <string name="space_settings_manage_rooms">Beheer kamers</string> <string name="space_leave_prompt_msg_as_admin">U bent de enige beheerder van deze kamer. Als u het verlaat, betekent dit dat niemand er controle over heeft.</string> <string name="room_alias_preview_not_found">Deze alias is momenteel niet toegankelijk. @@ -2229,7 +2188,7 @@ <string name="tooltip_attachment_contact">Contacten openen</string> <string name="tooltip_attachment_sticker">Stuur sticker</string> <string name="tooltip_attachment_file">Upload bestand</string> - <string name="tooltip_attachment_gallery">Afbeeldingen en video\'s verzenden</string> + <string name="tooltip_attachment_gallery">Afbeeldingen en video\'s versturen</string> <string name="tooltip_attachment_photo">Open camera</string> <string name="delete_poll_dialog_content">Weet u zeker dat u deze poll wilt verwijderen\? U kunt het niet meer herstellen nadat het is verwijderd.</string> <string name="delete_poll_dialog_title">Poll verwijderen</string> @@ -2279,10 +2238,10 @@ <string name="a11y_start_voice_message">Spraakbericht opnemen</string> <string name="error_failed_to_join_room">Sorry, er is een fout opgetreden bij het proberen deel te nemen aan: %s</string> <string name="room_upgrade_to_recommended_version">Upgrade naar de aanbevolen kamerversie</string> - <string name="room_using_unstable_room_version">In deze kamer wordt versie %s gebruikt, die door deze thuisserver als onstabiel is gemarkeerd.</string> + <string name="room_using_unstable_room_version">In deze kamer wordt versie %s gebruikt, die door deze server als onstabiel is gemarkeerd.</string> <string name="upgrade_room_no_power_to_manage">U heeft toestemming nodig om een kamer te upgraden</string> <string name="upgrade_room_update_parent_space">Bovenliggende space automatisch bijwerken</string> - <string name="upgrade_room_auto_invite">Gebruikers automatisch uitnodigen</string> + <string name="upgrade_room_auto_invite">Personen automatisch uitnodigen</string> <string name="upgrade_public_room_from_to">U update de kamer van %1$s naar %2$s.</string> <string name="upgrade_private_room">Upgrade privékamer</string> <string name="upgrade_public_room">Upgrade openbare kamer</string> @@ -2294,8 +2253,8 @@ <string name="this_space_has_no_rooms_not_admin">Sommige kamers zijn mogelijk verborgen omdat ze privé zijn en u een uitnodiging nodig heeft. \nU heeft geen rechten om kamers toe te voegen.</string> <string name="this_space_has_no_rooms">Deze space heeft geen kamers</string> - <string name="spaces_no_server_support_description">Neem contact op met uw thuisserver beheerder voor meer informatie</string> - <string name="spaces_no_server_support_title">Het lijkt erop dat je thuisserver nog geen Spaces ondersteunt</string> + <string name="spaces_no_server_support_description">Neem contact op met uw server beheerder voor meer informatie</string> + <string name="spaces_no_server_support_title">Het lijkt erop dat je server nog geen Spaces ondersteunt</string> <string name="spaces_feeling_experimental_subspace">Experimenteel voelen\? \nU kunt bestaande spaces aan een space toevoegen.</string> <string name="all_rooms_youre_in_will_be_shown_in_home">Alle kamers waarin u deelneemt, worden weergegeven in Home.</string> @@ -2319,9 +2278,9 @@ <string name="space_leave_prompt_msg_private">U kunt pas weer deelnemen als u opnieuw wordt uitgenodigd.</string> <string name="space_leave_prompt_msg_only_you">U bent de enige persoon hier. Als u weggaat, kan niemand meer meedoen, ook u niet.</string> <string name="space_leave_prompt_msg_with_name">Weet u zeker dat u %s wilt verlaten\?</string> - <string name="leave_space">Verlaat Space</string> + <string name="leave_space">Verlaat</string> <string name="space_add_child_title">Kamers toevoegen</string> - <string name="space_explore_activity_title">Kamers verkennen</string> + <string name="space_explore_activity_title">Kamers ontdekken</string> <plurals name="space_people_you_know"> <item quantity="one">%d persoon die u kent is al lid geworden</item> <item quantity="other">%d mensen die u kent zijn al lid geworden</item> @@ -2336,10 +2295,10 @@ <string name="skip_for_now">Voor nu overslaan</string> <string name="invite_just_to_this_room_desc">Ze zullen geen deel uitmaken van %s</string> <string name="invite_just_to_this_room">Alleen voor deze kamer</string> - <string name="invite_to_space_with_name_desc">Ze kunnen %s verkennen</string> + <string name="invite_to_space_with_name_desc">Ze kunnen %s ontdekken</string> <string name="invite_to_space_with_name">Uitnodigen voor %s</string> <string name="invite_by_link">Deel link</string> - <string name="invite_by_username_or_mail">Uitnodigen via gebruikersnaam of e-mail</string> + <string name="invite_by_username_or_mail">Uitnodigen via inlognaam of e-mailadres</string> <string name="invite_by_email">uitnodiging via e-mail</string> <string name="invite_people_to_your_space_desc">Het is alleen u op dit moment. %s zal nog beter zijn met anderen.</string> <string name="invite_to_space">Uitnodigen voor %s</string> @@ -2360,10 +2319,10 @@ <string name="create_spaces_me_and_teammates">Ik en teamgenoten</string> <string name="create_spaces_organise_rooms">Een privé space om je kamers te organiseren</string> <string name="create_spaces_just_me">Alleen ik</string> - <string name="create_spaces_make_sure_access">Zorg ervoor dat de juiste mensen toegang hebben tot %s. U kunt dit later wijzigen.</string> + <string name="create_spaces_make_sure_access">Zorg ervoor dat de juiste mensen toegang hebben tot %s.</string> <string name="create_spaces_who_are_you_working_with">Met wie werkt u samen\?</string> <string name="create_spaces_you_can_change_later">U kunt dit later wijzigen</string> - <string name="create_spaces_choose_type_label">Wat voor soort space wilt u creëren\?</string> + <string name="create_spaces_choose_type_label">Wat voor soort space wilt u aanmaken\?</string> <string name="your_private_space">Uw privé space</string> <string name="your_public_space">Uw openbare space</string> <string name="add_space">Space toevoegen</string> @@ -2371,7 +2330,7 @@ <string name="public_space">Openbare space</string> <string name="event_status_delete_all_failed_dialog_title">Niet verzonden berichten verwijderen</string> <string name="event_status_failed_messages_warning">Berichten kunnen niet worden verzonden</string> - <string name="event_status_cancel_sending_dialog_message">Wilt u het verzenden van een bericht annuleren\?</string> + <string name="event_status_cancel_sending_dialog_message">Wilt u het versturen van een bericht annuleren\?</string> <string name="event_status_a11y_delete_all">Alle mislukte berichten verwijderen</string> <string name="command_description_upgrade_room">Upgrade een kamer naar een nieuwe versie</string> <string name="command_description_leave_room">Verlaat kamer met gegeven id (of huidige kamer indien leeg)</string> @@ -2383,7 +2342,7 @@ <string name="ftue_auth_carousel_encrypted_title">Veilig berichtenverkeer.</string> <string name="ftue_auth_carousel_control_title">U heeft de controle.</string> <string name="tooltip_attachment_location">Deel locatie</string> - <string name="labs_render_locations_in_timeline">Gebruikerslocaties in de tijdlijn weergeven</string> + <string name="labs_render_locations_in_timeline">Persoonslocaties in de tijdlijn weergeven</string> <string name="settings_enable_location_sharing_summary">Eenmaal ingeschakeld, kun je je locatie naar elke kamer sturen</string> <string name="settings_enable_location_sharing">Locatie delen inschakelen</string> <string name="location_share_external">Open met</string> @@ -2411,8 +2370,8 @@ <string name="ftue_auth_carousel_control_body">Kies waar je gesprekken worden bewaard, zodat u controle en onafhankelijkheid heeft. Verbonden via Matrix.</string> <string name="ftue_auth_carousel_secure_body">Veilige en onafhankelijke communicatie die u dezelfde mate van privacy geeft als een persoonlijk gesprek in uw eigen huis.</string> <string name="attachment_type_location">Locatie</string> - <string name="room_unsupported_e2e_algorithm_as_admin">De versleuteling is verkeerd geconfigureerd, zodat u geen berichten kunt verzenden. Klik om instellingen te openen.</string> - <string name="room_unsupported_e2e_algorithm">De versleuteling is verkeerd geconfigureerd, zodat u geen berichten kunt verzenden. Neem contact op met een beheerder om de versleuteling in een geldige staat te herstellen.</string> + <string name="room_unsupported_e2e_algorithm_as_admin">De versleuteling is verkeerd geconfigureerd, zodat u geen berichten kunt versturen. Klik om instellingen te openen.</string> + <string name="room_unsupported_e2e_algorithm">De versleuteling is verkeerd geconfigureerd, zodat u geen berichten kunt versturen. Neem contact op met een beheerder om de versleuteling in een geldige staat te herstellen.</string> <string name="message_bubbles">Toon bericht bubbels</string> <string name="location_timeline_failed_to_load_map">Kan kaart niet laden</string> <string name="a11y_static_map_image">Kaart</string> @@ -2446,4 +2405,56 @@ <string name="action_thread_copy_link_to_thread">Kopieer link naar discussie</string> <string name="action_thread_view_in_room">Bekijk in kamer</string> <string name="action_view_threads">Discussies bekijken</string> + <string name="room_message_autocomplete_users">Personen</string> + <string name="error_forbidden_digits_only_username">De server accepteert geen inlognaam met alleen cijfers.</string> + <string name="room_message_autocomplete_notification">Kamer notificatie</string> + <string name="room_message_notify_everyone">Breng de hele kamer op de hoogte</string> + <plurals name="message_reaction_show_more"> + <item quantity="one">%1$d meer</item> + <item quantity="other">%1$d meer</item> + </plurals> + <string name="message_reaction_show_less">Toon minder</string> + <string name="live_location_sharing_notification_description">Locatie delen is bezig</string> + <string name="live_location_sharing_notification_title">${app_name} Live locatie</string> + <string name="location_share_live_stop">Stop</string> + <string name="location_share_live_enabled">Live locatie ingeschakeld</string> + <string name="location_in_background_missing_permission_dialog_content">Als u de Live-locatie wilt delen, heeft ${app_name} altijd locatietoegang nodig als de app op de achtergrond actief is. +\nWe hebben alleen toegang tot uw locatie voor de duur die u kiest.</string> + <string name="location_in_background_missing_permission_dialog_title">Toegang te verlenen</string> + <string name="a11y_location_share_option_pinned_icon">Deel deze locatie</string> + <string name="location_share_option_pinned">Deel deze locatie</string> + <string name="a11y_location_share_option_user_live_icon">Live locatie delen</string> + <string name="location_share_option_user_live">Live locatie delen</string> + <string name="a11y_location_share_option_user_current_icon">Deel mijn huidige locatie</string> + <string name="location_share_option_user_current">Deel mijn huidige locatie</string> + <string name="a11y_location_share_locate_button">Zoom naar huidige locatie</string> + <string name="a11y_location_share_pin_on_map">Pin van geselecteerde locatie op kaart</string> + <string name="ftue_personalize_skip_this_step">Sla deze stap over</string> + <string name="ftue_personalize_submit">Opslaan en doorgaan</string> + <string name="ftue_personalize_complete_subtitle">Je voorkeuren zijn opgeslagen.</string> + <string name="ftue_personalize_complete_title">Alles gereed!</string> + <string name="ftue_personalize_lets_go">Laten we beginnen</string> + <string name="ftue_profile_picture_subtitle">U kunt dit op elk moment wijzigen.</string> + <string name="ftue_profile_picture_title">Voeg een profielfoto toe</string> + <string name="ftue_display_name_entry_footer">U kunt dit later wijzigen</string> + <string name="ftue_display_name_entry_title">Weergavenaam</string> + <string name="ftue_display_name_subtitle">Dit wordt weergegeven wanneer u berichten verzendt.</string> + <string name="ftue_display_name_title">Kies een weergavenaam</string> + <string name="ftue_account_created_subtitle">Uw account %s is aangemaakt.</string> + <string name="ftue_account_created_congratulations_title">Gefeliciteerd!</string> + <string name="ftue_account_created_take_me_home">Breng me naar het begin</string> + <string name="ftue_account_created_personalize">Personaliseer profiel</string> + <string name="threads_notice_migration_message">We komen dichter bij het uitbrengen van een openbare bèta voor Discussies. +\n +\nTerwijl we ons erop voorbereiden, moeten we enkele wijzigingen aanbrengen: discussies die vóór dit punt zijn gemaakt, worden weergegeven als gewone antwoorden. +\n +\nDit zal een eenmalige overgang zijn, aangezien Discussies nu deel uitmaken van de Matrix-specificatie.</string> + <string name="threads_notice_migration_title">Discussies die bèta naderen 🎉</string> + <string name="room_notification_more_than_two_users_are_typing">%1$s, %2$s en anderen</string> + <string name="room_notification_two_users_are_typing">%1$s en %2$s</string> + <string name="action_disable">Uitzetten</string> + <plurals name="notice_room_server_acl_changes"> + <item quantity="one">%d server ACL\'s veranderen</item> + <item quantity="other">%d server ACL\'s wijzigingen</item> + </plurals> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-pl/strings.xml b/vector/src/main/res/values-pl/strings.xml index fe98d6b6a1..9c1e9a9264 100644 --- a/vector/src/main/res/values-pl/strings.xml +++ b/vector/src/main/res/values-pl/strings.xml @@ -1,5 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> -<resources> +<resources xmlns:tools="http://schemas.android.com/tools"> <string name="notice_room_invite_no_invitee">Zaproszenie od %s</string> <string name="notice_room_invite">%1$s zaprosił(a) %2$s</string> <string name="notice_room_invite_you">%1$s zaprosił(a) Cię</string> @@ -287,22 +287,21 @@ <string name="permissions_rationale_msg_camera_and_audio">${app_name} wymaga dostępu do kamery i mikrofonu, aby przeprowadzać rozmowy wideo. \n \nPrzyznaj dostęp w następnym oknie.</string> - <string name="list_members">Lista uczestników</string> + <string name="list_members">Członkowie</string> <plurals name="room_title_members"> - <item quantity="one">1 członek</item> - <item quantity="few">kilku członków</item> + <item quantity="one">%d członek</item> + <item quantity="few">%d członków</item> <item quantity="many">%d członków</item> - <item quantity="other"/> + <item quantity="other">%d członków</item> </plurals> <string name="room_participants_power_level_prompt">Nie będziesz w stanie cofnąć tej zmiany, ponieważ przyznajesz użytkownikowi uprawnienia równe swoim. -\n \nJesteś pewien\?</string> - <string name="room_participants_ban_prompt_msg">Zbanowanie użytkownika usunie go z tego pokoju i uniemożliwi ponowne dołączenie.</string> + <string name="room_participants_ban_prompt_msg">Zablokowanie użytkownika usunie go z tego pokoju i uniemożliwi ponowne dołączenie.</string> <plurals name="room_new_messages_notification"> - <item quantity="one">Nowa wiadomość</item> - <item quantity="few">Kilka nowych wiadomości</item> + <item quantity="one">%d nowa wiadomość</item> + <item quantity="few">%d nowe wiadomości</item> <item quantity="many">%d nowych wiadomości</item> - <item quantity="other"/> + <item quantity="other">%d nowych wiadomości</item> </plurals> <string name="ssl_cert_not_trust">Może to oznaczać że ktoś zakłóca twoje połączenie, lub Twój telefon nie ufa certyfikatowi dostarczonemu przez zdalny serwer.</string> <string name="ssl_cert_new_account_expl">Jeśli administrator serwera oświadczył, że jest to oczekiwane, upewnij się, że poniższy odcisk palca odpowiada odciskowi palca dostarczonemu przez niego.</string> @@ -539,7 +538,8 @@ <plurals name="keys_backup_restore_success_description_part1"> <item quantity="one">Przywrócono kopię zapasową z %d kluczem.</item> <item quantity="few">Przywrócono kopię zapasową z %d kluczami.</item> - <item quantity="many"/> + <item quantity="many">Przywrócono kopię zapasową z %d kluczami.</item> + <item quantity="other">Przywrócono kopię zapasową z %d kluczami.</item> </plurals> <string name="title_activity_keys_backup_restore">Użyj kopii zapasowej klucza</string> <string name="settings_troubleshoot_diagnostic_running_status">Uruchamianie… (%1$d z %2$d)</string> @@ -736,7 +736,7 @@ \nMenedżerzy integracji odbierają dane konfiguracji, modyfikują widżety, wysyłają zaproszenia do pokojów i ustawiają poziomy uprawnień w Twoim imieniu.</string> <string name="settings_inline_url_preview_summary">Pokaż podgląd linków wewnątrz czatu jeśli twój serwer wspiera tę funkcję.</string> <string name="settings_send_markdown_summary">Formatuj wiadomości używając składni Markdown zanim zostaną wysłane. Pozwala to na zaawansowane formatowanie takie jak używanie asterysków do wyświetlania tekstu w kursywie.</string> - <string name="settings_show_join_leave_messages_summary">Nie wpływa to na zaproszenia, wyrzucenia oraz bany.</string> + <string name="settings_show_join_leave_messages_summary">Zaproszenia, usunięcia i bany pozostają nienaruszone.</string> <string name="settings_send_message_with_enter">Wysyłaj wiadomości za pomocą klawisza enter</string> <string name="settings_send_message_with_enter_summary">Przycisk enter na klawiaturze programowej wyśle wiadomość zamiast wprowadzania łamanania linii</string> <string name="settings_discovery_category">Znajdź</string> @@ -747,13 +747,14 @@ <plurals name="notification_compat_summary_line_for_room"> <item quantity="one">%1$s: %2$d wiadomość</item> <item quantity="few">%1$s: %2$d wiadomości</item> - <item quantity="many"/> - <item quantity="other"/> + <item quantity="many">%1$s: %2$d wiadomości</item> + <item quantity="other">%1$s: %2$d wiadomości</item> </plurals> <plurals name="notification_compat_summary_title"> <item quantity="one">%d powiadomienie</item> - <item quantity="few">%d powiadomień</item> - <item quantity="many"/> + <item quantity="few">%d powiadomienia</item> + <item quantity="many">%d powiadomień</item> + <item quantity="other">%d powiadomień</item> </plurals> <string name="notification_unknown_new_event">Nowe wydarzenie</string> <string name="notification_new_messages">Nowe wiadomości</string> @@ -825,9 +826,10 @@ <string name="keys_backup_banner_update_line2">Zarządzaj w Kopii Zapasowej Kluczy</string> <string name="keys_backup_banner_in_progress">Tworzenei kopii zapasowej kluczy…</string> <plurals name="keys_backup_info_keys_backing_up"> - <item quantity="one">Kopiowanie %d klucza…</item> - <item quantity="few">Kopiowanie %d kluczy…</item> - <item quantity="many"/> + <item quantity="one">Tworzenie kopii zapasowej %d klucza…</item> + <item quantity="few">Tworzenie kopii zapasowej %d kluczy…</item> + <item quantity="many">Tworzenie kopii zapasowej %d kluczy…</item> + <item quantity="other">Tworzenie kopii zapasowej %d kluczy…</item> </plurals> <string name="settings_troubleshoot_test_bing_settings_failed">Niektóre powiadomienia są wyłączone w osobistej konfiguracji.</string> <string name="settings_troubleshoot_test_play_services_success">Usługi Google Play są aktualne.</string> @@ -888,8 +890,8 @@ <plurals name="fallback_users_read"> <item quantity="one">%d użytkownik odczytał</item> <item quantity="few">%d użytkowników odczytało</item> - <item quantity="many"/> - <item quantity="other"/> + <item quantity="many">%d użytkowników odczytało</item> + <item quantity="other">%d użytkowników odczytało</item> </plurals> <string name="error_attachment">Wystąpił błąd poczas otrzymywania załącznika.</string> <string name="error_handling_incoming_share">Nie można obsłużyć otrzymanych danych</string> @@ -999,9 +1001,10 @@ <string name="login_validation_code_is_not_correct">Wprowadzony kod jest nieprawidłowy. Sprawdź.</string> <string name="login_error_outdated_homeserver_title">Nieaktualny serwer domowy</string> <plurals name="login_error_limit_exceeded_retry_after"> - <item quantity="one">Zostało wysłane zbyt wiele żądań. Możesz spróbować ponownie za %1$d sekundę…</item> - <item quantity="few">Zostało wysłane zbyt wiele żądań. Możesz spróbować ponownie za %1$d sekundy…</item> - <item quantity="many"/> + <item quantity="one">Wysłano zbyt wiele próśb. Możesz spróbować ponownie za %1$d sekundę…</item> + <item quantity="few">Wysłano zbyt wiele próśb. Możesz spróbować ponownie za %1$d sekundy…</item> + <item quantity="many">Wysłano zbyt wiele próśb. Możesz spróbować ponownie za %1$d sekund…</item> + <item quantity="other">Wysłano zbyt wiele próśb. Możesz spróbować ponownie za %1$d sekund…</item> </plurals> <string name="signed_out_title">Wylogowałeś(-łaś) się</string> <string name="signed_out_notice">Mogło to się stać z wielu powodów: @@ -1081,8 +1084,9 @@ <string name="room_profile_section_security_learn_more">Dowiedz się więcej</string> <plurals name="room_profile_section_more_member_list"> <item quantity="one">Jedna osoba</item> - <item quantity="few">%1$d osób</item> - <item quantity="many"/> + <item quantity="few">%1$d osoby</item> + <item quantity="many">%1$d osób</item> + <item quantity="other">%1$d osób</item> </plurals> <string name="room_profile_leaving_room">Opuszczanie pokoju…</string> <string name="room_member_power_level_admins">Administratorzy</string> @@ -1104,8 +1108,7 @@ <string name="settings_category_timeline">Oś czasu</string> <string name="settings_category_composer">Edycja wiadomości</string> <string name="room_settings_enable_encryption_dialog_title">Aktywować szyfrowanie\?</string> - <string name="room_settings_enable_encryption_dialog_content">Raz włączone szyfrowanie w pokoju nie może zostać wyłączone. Wiadomości wysłane w zaszyfrowanym pokoju nie są widziane przez serwer, a jedynie przez uczestników w pokoju. -\nAktywowanie szyfrowania może uniemożliwić wielu botom i mostom prawidłowe działanie.</string> + <string name="room_settings_enable_encryption_dialog_content">Raz włączone szyfrowanie w pokoju nie może zostać wyłączone. Wiadomości wysłane w zaszyfrowanym pokoju nie są widziane przez serwer, a jedynie przez uczestników w pokoju. Aktywowanie szyfrowania może uniemożliwić wielu botom i mostkom prawidłowe działanie.</string> <string name="room_settings_enable_encryption_dialog_submit">Aktywuj szyfrowanie</string> <string name="verification_request_notice">Aby być bezpiecznym, zweryfikuj %s poprzez sprawdzenie jednorazowego kodu.</string> <string name="verification_request_start_notice">Aby być bezpiecznym, zrób to osobiście lub użyj innej metody komunikacji.</string> @@ -1131,8 +1134,9 @@ <string name="settings_active_sessions_unverified_device_desc">Zweryfikuj tą sesję aby oznaczyć ją jako zaufaną i przyznać jej dostęp do zaszyfrowanych wiadomości. Jeżeli nie logowałeś(-łaś) się do tej sesji, twoje konto mogło zostać naruszone:</string> <plurals name="settings_active_sessions_count"> <item quantity="one">%d aktywna sesja</item> - <item quantity="few">%d aktywnych sesji</item> - <item quantity="many"/> + <item quantity="few">%d aktywne sesje</item> + <item quantity="many">%d aktywnych sesji</item> + <item quantity="other">%d aktywnych sesji</item> </plurals> <string name="crosssigning_verify_this_session">Zweryfikuj tą sesję</string> <string name="verification_open_other_to_verify">Otwórz obecną sesję i użyj jej do zweryfikowania obecnej, przyznając jej dostęp do zaszyfrowanych wiadomości.</string> @@ -1161,7 +1165,8 @@ <plurals name="send_images_with_original_size"> <item quantity="one">Wyślij obraz w oryginalnym rozmiarze</item> <item quantity="few">Wyślij obrazy w oryginalnym rozmiarze</item> - <item quantity="many"/> + <item quantity="many">Wyślij obrazów w oryginalnym rozmiarze</item> + <item quantity="other">Wyślij obrazów w oryginalnym rozmiarze</item> </plurals> <string name="delete_event_dialog_title">Potwierdź Usunięcie</string> <string name="delete_event_dialog_content">Jesteś pewny(-na), że chcesz usunąć to wydarzenie\? Jeżeli usuniesz nazwę pokoju lub zmienisz temat, wciąż będzie możliwe cofnięcie zmiany.</string> @@ -1354,9 +1359,9 @@ <string name="active_widget_view_action">WIDOK</string> <plurals name="seconds"> <item quantity="one">%d sekunda</item> - <item quantity="few">%d sek.</item> - <item quantity="many">%d sek.</item> - <item quantity="other">%d sek.</item> + <item quantity="few">%d sekundy</item> + <item quantity="many">%d sekund</item> + <item quantity="other">%d sekund</item> </plurals> <string name="settings_troubleshoot_test_push_loop_success">Aplikacja odebrała PUSH</string> <string name="settings_troubleshoot_test_push_loop_title">Przetestuj powiadomienia push</string> @@ -1581,10 +1586,10 @@ <string name="send_a_sticker">Naklejka</string> <string name="direct_room_join_rules_invite">%1$s wymaga otrzymania zaproszenia do dołączenia.</string> <plurals name="two_and_some_others_read"> - <item quantity="one">%1$s, %2$s i %3$d czyta</item> - <item quantity="few">%1$s, %2$s i %3$d czytają</item> - <item quantity="many"/> - <item quantity="other"/> + <item quantity="one">%1$s, %2$s i %3$d inny czyta</item> + <item quantity="few">%1$s, %2$s i %3$d innych czyta</item> + <item quantity="many">%1$s, %2$s i %3$d innych czyta</item> + <item quantity="other">%1$s, %2$s i %3$d innych czyta</item> </plurals> <string name="room_alias_publish_to_directory_error">Nie udało się uzyskać widoczności katalogu bieżącego pokoju (%1$s).</string> <string name="settings_secure_backup_enter_to_setup">Skonfiguruj na tym urządzeniu</string> @@ -1793,18 +1798,18 @@ <string name="room_displayname_3_members">%1$s, %2$s i %3$s</string> <string name="link_this_email_with_your_account">%s w Ustawieniach, aby otrzymywać zaproszenia bezpośrednio w ${app_name}.</string> <string name="room_permissions_change_topic">Zmiana tematu</string> - <string name="room_permissions_upgrade_the_space">Aktualizacja Przestrzeni</string> + <string name="room_permissions_upgrade_the_space">Aktualizacja przestrzeni</string> <string name="room_permissions_upgrade_the_room">Aktualizacja pokoju</string> <string name="room_permissions_send_m_room_server_acl_events">Wysyłanie zdarzeń m.room.server_acl</string> <string name="room_permissions_change_permissions">Zmiana uprawnień</string> - <string name="room_permissions_change_space_name">Zmiana nazwy Przestrzeni</string> + <string name="room_permissions_change_space_name">Zmiana nazwy przestrzeni</string> <string name="room_permissions_change_room_name">Zmiana nazwy pokoju</string> <string name="room_permissions_change_history_visibility">Zmiana widoczności historii</string> <string name="room_permissions_enable_space_encryption">Włączanie szyfrowania przestrzeni</string> <string name="room_permissions_enable_room_encryption">Włączanie szyfrowania pokoju</string> - <string name="room_permissions_change_main_address_for_the_space">Zmiana głównego adresu Przestrzeni</string> + <string name="room_permissions_change_main_address_for_the_space">Zmiana głównego adresu przestrzeni</string> <string name="room_permissions_change_main_address_for_the_room">Zmiana głównego adresu pokoju</string> - <string name="room_permissions_change_space_avatar">Zmiana awatara Przestrzeni</string> + <string name="room_permissions_change_space_avatar">Zmiana awatara przestrzeni</string> <string name="room_permissions_change_room_avatar">Zmiana awatara pokoju</string> <string name="room_permissions_modify_widgets">Modyfikowanie widgetów</string> <string name="room_permissions_notify_everyone">Powiadamianie wszystkich</string> @@ -1825,7 +1830,7 @@ <string name="space_settings_permissions_title">Uprawnienia Przestrzeni</string> <string name="room_settings_permissions_title">Uprawnienia pokoju</string> <string name="space_participants_unban_prompt_msg">Odblokowanie użytkownika pozwoli mu na ponowne dołączenie do tej przestrzeni.</string> - <string name="space_participants_ban_prompt_msg">Blokowanie użytkowników wyrzuci ich z tej przestrzeni i uniemożliwi im dołączenie ponownie.</string> + <string name="space_participants_ban_prompt_msg">Zablokowanie użytkownika usunie go z tego miejsca i uniemożliwi ponowne dołączenie.</string> <string name="room_participants_leave_private_warning">Ten pokój jest prywatny. Nie będziesz w stanie dołączyć bez zaproszenia.</string> <string name="call_remove_jitsi_widget_progress">Zakańczanie połączenia…</string> <string name="call_ended_invite_timeout_title">Brak odpowiedzi</string> @@ -1947,7 +1952,7 @@ <string name="this_space_has_no_rooms_admin">Niektóre pokoje mogą być ukryte, gdyż są prywatne i wymagają od Ciebie zaproszenia.</string> <string name="this_space_has_no_rooms_not_admin">Niektóre pokoje mogą być ukryte, gdyż są prywatne i wymagają od Ciebie zaproszenia. \nNie masz uprawnień aby dodawać pokoje.</string> - <string name="this_space_has_no_rooms">W tej Przestrzeni nie ma żadnych pokojów</string> + <string name="this_space_has_no_rooms">W tej przestrzeni nie ma żadnych pokojów</string> <string name="spaces_no_server_support_description">Proszę skontaktować się z administratorem Twojego serwera domowego aby uzyskać więcej informacji</string> <string name="spaces_no_server_support_title">Wygląda na to, że Twój serwer domowy jeszcze nie obsługuje Przestrzeni</string> <string name="spaces_feeling_experimental_subspace">Lubisz eksperymentować\? @@ -1975,7 +1980,7 @@ <string name="space_leave_prompt_msg_private">Nie będziesz w stanie ponownie dołączyć, do momentu kiedy nie zostaniesz ponownie zaproszony.</string> <string name="space_leave_prompt_msg_only_you">Jesteś jedyną osoba tutaj. Jeśli wyjdziesz, nikt nie będzie w stanie dołączyć w przyszłości, włączając Ciebie.</string> <string name="space_leave_prompt_msg_with_name">Czy jesteś pewny, że chcesz opuścić %s\?</string> - <string name="leave_space">Opuść przestrzeń</string> + <string name="leave_space">Opuść</string> <string name="space_add_child_title">Dodawaj pokoje</string> <string name="space_explore_activity_title">Przeglądaj pokoje</string> <string name="finish_setup">Ukończ konfigurację</string> @@ -1985,7 +1990,7 @@ \nSpróbuj ponownie później lub zapytaj administratora tego pokoju czy masz dostęp.</string> <string name="join_anyway">Dołącz pomimo to</string> <string name="join_space">Dołącz do przestrzeni</string> - <string name="create_space">Stwórz przestrzeń</string> + <string name="create_space">Utwórz przestrzeń</string> <string name="skip_for_now">Na razie pomiń</string> <string name="share_space_link_message">Dołącz do mojej przestrzeni %1$s %2$s</string> <string name="invite_just_to_this_room_desc">Nie będą częścią %s</string> @@ -2016,7 +2021,7 @@ <string name="create_spaces_me_and_teammates">Ja i moi znajomi</string> <string name="create_spaces_organise_rooms">Prywatna przestrzeń do organizacji Twoich pokojów</string> <string name="create_spaces_just_me">Tylko ja</string> - <string name="create_spaces_make_sure_access">Upewnij się, że odpowiednie osoby mają dostęp do %s. Możesz zmienić to później.</string> + <string name="create_spaces_make_sure_access">Upewnij się, że odpowiednie osoby mają dostęp do %s.</string> <string name="create_spaces_who_are_you_working_with">Z kim pracujesz\?</string> <string name="create_spaces_join_info_help">Aby dołączyć do istniejącej przestrzeni, potrzebujesz zaproszenia.</string> <string name="create_spaces_you_can_change_later">Możesz zmienić to później</string> @@ -2028,10 +2033,10 @@ \nCzekanie na odpowiedź serwera…</string> <string name="room_displayname_empty_room_was">Pusty pokój (było %s)</string> <plurals name="room_displayname_four_and_more_members"> - <item quantity="one">%1$s, %2$s, %3$s i %4$d innych</item> + <item quantity="one">%1$s, %2$s, %3$s i %4$d inny</item> <item quantity="few">%1$s, %2$s, %3$s i %4$d innych</item> - <item quantity="many"/> - <item quantity="other"/> + <item quantity="many">%1$s, %2$s, %3$s i %4$d innych</item> + <item quantity="other">%1$s, %2$s, %3$s i %4$d innych</item> </plurals> <string name="room_displayname_4_members">%1$s, %2$s, %3$s i %4$s</string> <string name="power_level_custom_no_value">Niestandardowe</string> @@ -2105,7 +2110,7 @@ <string name="decide_who_can_find_and_join">Zdecyduj kto może odnaleźć i dołączyć do tego pokoju.</string> <string name="tap_to_edit_spaces">Dotknij, aby edytować przestrzenie</string> <string name="select_spaces">Wybierz przestrzenie</string> - <string name="decide_which_spaces_can_access">Zdecyduj które przestrzenie mogą mieć dostęp do tego pokoju. Członkowie wybranej przestrzeni będą mogli ją odnaleźć i dołączyć do Pokoju przez nazwę.</string> + <string name="decide_which_spaces_can_access">Zdecyduj, które przestrzenie mogą mieć dostęp do tego pokoju. Członkowie zaznaczonej przestrzeni będą mogli odnaleźć i dołączyć do nazwy pokoju.</string> <string name="spaces_which_can_access">Przestrzenie mogące uzyskać dostęp</string> <string name="allow_space_member_to_find_and_access">Zezwól użytkownikom przestrzeni na znalezienie i dostęp.</string> <string name="settings_room_upgrades">Ulepszenia pokoju</string> @@ -2208,7 +2213,7 @@ <item quantity="other">Dodano %1$s jako adresy dla tego pokoju.</item> </plurals> <string name="login_social_sso">pojedyncze logowanie</string> - <string name="shortcut_disabled_reason_room_left">Pokój opuszczony!</string> + <string name="shortcut_disabled_reason_room_left">Pokój został opuszczony!</string> <string name="call_dial_pad_lookup_error">Błąd podczas wyszukiwania numeru telefonu</string> <string name="call_transfer_title">Przekaż</string> <string name="call_tap_to_return">%1$s dotknij by powrócić</string> @@ -2328,10 +2333,221 @@ <string name="preference_help_summary">Uzyskaj pomoc w korzystaniu z ${app_name}</string> <string name="room_error_access_unauthorized">Nie masz uprawnień by dołączyć do tego pokoju</string> <string name="dev_tools_form_hint_type">Typ</string> - <string name="a11y_presence_offline">Niedostępny</string> - <string name="a11y_presence_online">Dostępny</string> - <string name="a11y_view_read_receipts">Pokaż znaczniki odczytania</string> + <string name="a11y_presence_offline">Offline</string> + <string name="a11y_presence_online">Online</string> + <string name="a11y_view_read_receipts">Wyświetl znaczniki odczytania</string> <string name="discovery_section">Odkrywanie (%s)</string> <string name="finish_setting_up_discovery">Dokończ konfigurację odkrywania.</string> <string name="event_status_a11y_delete_all">Usuń wszystkie nieudane wiadomości</string> + <string name="bootstrap_migration_with_passphrase_helper_with_link">Nie znasz hasła swojego zapasowego klucza\? Możesz %s.</string> + <plurals name="entries"> + <item quantity="one">%d wpis</item> + <item quantity="few">%d wpisy</item> + <item quantity="many">%d wpisów</item> + <item quantity="other">%d wpisów</item> + </plurals> + <plurals name="space_people_you_know"> + <item quantity="one">%d osoba, którą znasz, już dołączyła</item> + <item quantity="few">%d osoby, które znasz, już dołączyły</item> + <item quantity="many">%d osób, które znasz, już dołączyły</item> + <item quantity="other">%d osób, które znasz, już dołączyły</item> + </plurals> + <string name="dev_tools_error_no_message_type">Brakujący typ wiadomości</string> + <string name="dev_tools_error_no_content">Brak zawartości</string> + <string name="dev_tools_send_custom_event">Wyślij zdarzenie niestandardowe</string> + <string name="a11y_trust_level_warning">Ostrzegawczy poziom zaufania</string> + <string name="call_transfer_consult_first">Upewnij się najpierw</string> + <string name="a11y_unchecked">Nie sprawdzono</string> + <string name="a11y_checked">Sprawdzono</string> + <string name="restart_the_application_to_apply_changes">Aby zmiany zostały zastosowane, należy uruchomić ponownie aplikację.</string> + <string name="labs_enable_latex_maths">Włącz matematykę LaTeX</string> + <string name="poll_end_action">Zakończ ankietę</string> + <string name="end_poll_confirmation_title">Czy zakończyć ankietę\?</string> + <string name="end_poll_confirmation_description">To powstrzyma użytkowników od głosowania i wyświetli ostateczny wynik ankiety.</string> + <string name="labs_enable_thread_messages_desc">Uwaga: aplikacja zostanie uruchomiona ponownie</string> + <string name="labs_enable_thread_messages">Włącz wątkowanie wiadomości</string> + <string name="create_spaces_invite_public_header_desc">Upewnij się, że odpowiednie osoby mają dostęp do firmy %s. Więcej osób możesz zaprosić później.</string> + <string name="dev_tools_send_custom_state_event">Wyślij niestandardowe zdarzenie stanowe</string> + <string name="dev_tools_send_state_event">Wyślij zdarzenie stanowe</string> + <string name="dev_tools_state_event">Zdarzenia stanowe</string> + <string name="dev_tools_event_content_hint">Zawartość zdarzenia</string> + <string name="dev_tools_success_state_event">Zdarzenie stanowe wysłane!</string> + <string name="dev_tools_success_event">Zdarzenie wysłane!</string> + <string name="dev_tools_error_malformed_event">Nieprawidłowe zdarzenie</string> + <string name="dev_tools_form_hint_event_content">Zawartość wydarzenia</string> + <string name="dev_tools_form_hint_state_key">Klucz stanu</string> + <string name="call_transfer_consulting_with">Konsultacja z %1$s</string> + <string name="error_forbidden_digits_only_username">Serwer domowy nie akceptuje nazwy użytkownika zawierającej tylko cyfry.</string> + <string name="command_description_discard_session">Wymusza odrzucenie bieżącej sesji grupy wychodzącej w zaszyfrowanym pokoju</string> + <string name="bootstrap_progress_compute_curve_key">Pobieranie krzywego klucza</string> + <string name="encryption_misconfigured">Szyfrowanie jest błędnie skonfigurowane</string> + <string name="room_profile_section_restore_security">Przywróć szyfrowanie</string> + <string name="contact_admin_to_restore_encryption">Skontaktuj się z administratorem, aby przywrócić szyfrowanie do prawidłowego stanu.</string> + <string name="encryption_has_been_misconfigured">Szyfrowanie zostało błędnie skonfigurowane.</string> + <string name="login_splash_create_account">Utwórz konto</string> + <string name="ftue_personalize_skip_this_step">Pomiń ten krok</string> + <string name="ftue_personalize_submit">Zapisz i kontynuuj</string> + <string name="ftue_personalize_complete_subtitle">Twoje ustawienia zostały zapisane.</string> + <string name="ftue_personalize_complete_title">Wszystko ustawiłeś!</string> + <string name="ftue_personalize_lets_go">Chodźmy</string> + <string name="ftue_profile_picture_subtitle">Możesz go zmienić w każdym momencie.</string> + <string name="ftue_profile_picture_title">Dodaj obraz profilu</string> + <string name="ftue_display_name_entry_footer">Możesz zmienić ją później</string> + <string name="room_message_autocomplete_notification">Powiadomienie pokoju</string> + <string name="ftue_display_name_entry_title">Wyświetlana nazwa</string> + <string name="ftue_display_name_subtitle">Będzie ona widoczna podczas wysyłania wiadomości.</string> + <string name="ftue_display_name_title">Wybierz wyświetlaną nazwę</string> + <string name="ftue_account_created_subtitle">Twoje konto %s zostało utworzone.</string> + <string name="ftue_account_created_congratulations_title">Gratulacje!</string> + <string name="ftue_account_created_take_me_home">Zabierz mnie do domu</string> + <string name="ftue_account_created_personalize">Spersonalizuj profil</string> + <string name="ftue_auth_use_case_connect_to_server">Połącz się z serwerem</string> + <string name="ftue_auth_use_case_join_existing_server">Chcesz dołączyć do istniejącego serwera\?</string> + <string name="ftue_auth_use_case_skip_partial">pominąć to pytanie</string> + <string name="ftue_auth_use_case_skip">Nie wiesz jeszcze\? Możesz %s</string> + <string name="ftue_auth_use_case_option_three">Społeczności</string> + <string name="ftue_auth_use_case_option_two">Zespoły</string> + <string name="ftue_auth_use_case_option_one">Przyjaciele i rodzina</string> + <string name="ftue_auth_use_case_subtitle">Pomożemy Ci się połączyć.</string> + <string name="ftue_auth_use_case_title">Z kim będziesz najczęściej rozmawiać\?</string> + <string name="ftue_auth_carousel_encrypted_body">Szyfrowane od-końca-do-końca i nie wymaga numeru telefonu. Brak reklam i dataminingu.</string> + <string name="ftue_auth_carousel_control_body">Wybierz, gdzie prowadzone są Twoje rozmowy, dając Ci kontrolę i niezależność. Połączenie przez sieć Matrix.</string> + <string name="ftue_auth_carousel_secure_body">Bezpieczna i niezależna komunikacja, która zapewnia ten sam poziom prywatności, co rozmowa twarzą w twarz we własnym domu.</string> + <string name="ftue_auth_carousel_workplace_title">Wiadomości dla Twojego zespołu.</string> + <string name="attachment_type_location">Położenie</string> + <string name="preference_root_legals">Zagadnienia prawne</string> + <string name="navigate_to_thread_when_already_in_the_thread">Już przeglądasz ten wątek!</string> + <string name="view_in_room">Wyświetl w pokoju</string> + <string name="reply_in_thread">Odpowiedz w wątku</string> + <string name="command_not_supported_in_threads">Polecenie „%s” jest rozpoznawane, ale nie jest obsługiwane w wątkach.</string> + <string name="legals_no_policy_provided">Ten serwer nie zapewnia żadnych zasad.</string> + <string name="legals_identity_server_title">Polityka Twojego serwera tożsamości</string> + <string name="legals_home_server_title">Polityka Twojego serwera domowego</string> + <string name="legals_application_title">Polityka ${app_name}</string> + <string name="threads_notice_migration_title">Wątki zbliżają się do wersji beta 🎉</string> + <string name="search_thread_from_a_thread">Z wątku</string> + <string name="thread_list_empty_notice">Wskazówka: naciśnij i przytrzymaj wiadomość i użyj „%s”.</string> + <string name="thread_list_empty_subtitle">Dzięki wątkom Twoje rozmowy są aktualne i łatwe do śledzenia.</string> + <string name="thread_list_empty_title">Organizuj dyskusje za pomocą wątków</string> + <string name="thread_list_modal_my_threads_subtitle">Pokazuje wszystkie wątki, w których brałeś udział</string> + <string name="thread_list_modal_all_threads_subtitle">Pokazuje wszystkie wątki z bieżącego pokoju</string> + <string name="thread_list_modal_my_threads_title">Moje wątki</string> + <string name="thread_list_modal_all_threads_title">Wszystkie wątki</string> + <string name="thread_list_modal_title">Filtr</string> + <string name="thread_list_title">Wątki</string> + <string name="thread_timeline_title">Wątek</string> + <string name="room_threads_filter">Filtruj wątki w pokoju</string> + <string name="room_unsupported_e2e_algorithm_as_admin">Szyfrowanie zostało źle skonfigurowane, więc nie możesz wysyłać wiadomości. Kliknij, aby otworzyć ustawienia.</string> + <string name="room_unsupported_e2e_algorithm">Szyfrowanie zostało źle skonfigurowane, więc nie możesz wysyłać wiadomości. Skontaktuj się z administratorem, aby przywrócić szyfrowanie do prawidłowego stanu.</string> + <string name="room_notification_more_than_two_users_are_typing">%1$s, %2$s i inni</string> + <string name="room_notification_two_users_are_typing">%1$s i %2$s</string> + <string name="action_thread_copy_link_to_thread">Skopiuj odnośnik do wątku</string> + <string name="action_thread_view_in_room">Zobacz w pokoju</string> + <string name="action_disable">Wyłącz</string> + <string name="action_view_threads">Wyświetl wątki</string> + <string name="tooltip_attachment_poll">Utwórz ankietę</string> + <string name="tooltip_attachment_contact">Otwórz kontakty</string> + <string name="tooltip_attachment_sticker">Wyślij naklejkę</string> + <string name="tooltip_attachment_file">Prześlij plik</string> + <string name="tooltip_attachment_gallery">Wyślij obrazy oraz wideo</string> + <string name="tooltip_attachment_photo">Otwórz kamerę</string> + <string name="delete_poll_dialog_title">Usuń ankietę</string> + <string name="poll_end_room_list_preview">Ankieta zakończona</string> + <string name="poll_response_room_list_preview">Oddano głos</string> + <string name="end_poll_confirmation_approve_button">Zakończ ankietę</string> + <plurals name="message_reaction_show_more"> + <item quantity="one">I jeszcze %1$d</item> + <item quantity="few">I jeszcze %1$d</item> + <item quantity="many">I jeszcze %1$d</item> + <item quantity="other">I jeszcze %1$d</item> + </plurals> + <plurals name="poll_total_vote_count_after_ended"> + <item quantity="one">Wynik końcowy na podstawie %1$d głosu</item> + <item quantity="few">Wynik końcowy na podstawie %1$d głosów</item> + <item quantity="many">Wynik końcowy na podstawie %1$d głosów</item> + <item quantity="other">Wynik końcowy na podstawie %1$d głosów</item> + </plurals> + <plurals name="poll_total_vote_count_before_ended_and_not_voted"> + <item quantity="one">Oddano %1$d głos. Głosuj, aby zobaczyć wyniki</item> + <item quantity="few">Oddano %1$d głosy. Głosuj, aby zobaczyć wyniki</item> + <item quantity="many">Oddano %1$d głosów. Głosuj, aby zobaczyć wyniki</item> + <item quantity="other">Oddano %1$d głosów. Głosuj, aby zobaczyć wyniki</item> + </plurals> + <plurals name="poll_total_vote_count_before_ended_and_voted"> + <item quantity="one">W oparciu o %1$d głos</item> + <item quantity="few">W oparciu o %1$d głosy</item> + <item quantity="many">W oparciu o %1$d głosów</item> + <item quantity="other">W oparciu o %1$d głosów</item> + </plurals> + <plurals name="poll_option_vote_count"> + <item quantity="one">%1$d głos</item> + <item quantity="few">%1$d głosy</item> + <item quantity="many">%1$d głosów</item> + <item quantity="other">%1$d głosów</item> + </plurals> + <plurals name="create_poll_not_enough_options_error"> + <item quantity="one">Wymagana jest co najmniej %1$s opcja</item> + <item quantity="few">Wymagane są co najmniej %1$s opcje</item> + <item quantity="many">Wymaganych jest co najmniej %1$s opcji</item> + <item quantity="other">Wymaganych jest co najmniej %1$s opcji</item> + </plurals> + <string name="threads_notice_migration_message">Zbliżamy się do udostępnienia publicznej wersji beta dla wątków. +\n +\nPrzygotowując się do tego, musimy wprowadzić pewne zmiany: wątki utworzone przed tym punktem będą wyświetlane jako zwykłe odpowiedzi. +\n +\nBędzie to jednorazowe przejście, ponieważ wątki są teraz częścią specyfikacji Matrix.</string> + <plurals name="notice_room_server_acl_changes"> + <item quantity="one">%d zmieniony ACL serwera</item> + <item quantity="few">%d zmienione ACL serwera</item> + <item quantity="many">%d zmienionych ACL serwera</item> + <item quantity="other">%d zmienionych ACL serwera</item> + </plurals> + <string name="message_reaction_show_less">Pokaż mniej</string> + <string name="tooltip_attachment_location">Udostępnij lokalizację</string> + <string name="message_bubbles">Pokaż dymki wiadomości</string> + <string name="live_location_sharing_notification_description">Trwa udostępnianie lokalizacji</string> + <string name="live_location_sharing_notification_title">Lokalizacja na żywo ${app_name}</string> + <string name="location_share_live_stop">Zatrzymaj</string> + <string name="location_share_live_enabled">Włączona lokalizacja na żywo</string> + <string name="location_timeline_failed_to_load_map">Nie udało się wczytać mapy</string> + <string name="labs_render_locations_in_timeline">Renderuj lokalizacje użytkowników na osi czasu</string> + <string name="settings_enable_location_sharing_summary">Po włączeniu będziesz mógł wysłać swoją lokalizację do dowolnego pokoju</string> + <string name="settings_enable_location_sharing">Włącz udostępnianie lokalizacji</string> + <string name="location_share_external">Otwórz za pomocą</string> + <string name="location_not_available_dialog_content">${app_name} nie może uzyskać dostępu do Twojej lokalizacji. Spróbuj ponownie później.</string> + <string name="location_not_available_dialog_title">${app_name} nie może uzyskać dostępu do Twojej lokalizacji</string> + <string name="location_in_background_missing_permission_dialog_content">Jeśli chcesz udostępniać swoją lokalizację na żywo, ${app_name} potrzebuje dostępu do lokalizacji przez cały czas, gdy aplikacja działa w tle. +\n Będziemy mieć dostęp do Twojej lokalizacji tylko przez wybrany przez Ciebie okres.</string> + <string name="location_in_background_missing_permission_dialog_title">Zgoda na dostęp</string> + <string name="a11y_location_share_option_pinned_icon">Udostępnij tę lokalizację</string> + <string name="location_share_option_pinned">Udostępnij tę lokalizację</string> + <string name="a11y_location_share_option_user_live_icon">Udostępnij lokalizację na żywo</string> + <string name="location_share_option_user_live">Udostępnij lokalizację na żywo</string> + <string name="a11y_location_share_option_user_current_icon">Udostępnij moją aktualną lokalizację</string> + <string name="location_share_option_user_current">Udostępnij moją aktualną lokalizację</string> + <string name="a11y_location_share_locate_button">Powiększ do bieżącej lokalizacji</string> + <string name="a11y_location_share_pin_on_map">Przypnij na mapie wybraną lokalizację</string> + <string name="location_share" tools:ignore="UnusedResources">Udostępnij lokalizację</string> + <string name="a11y_static_map_image">Mapa</string> + <string name="a11y_location_share_icon" tools:ignore="UnusedResources">Udostępnij lokalizację</string> + <string name="location_activity_title_preview">Lokalizacja</string> + <string name="location_activity_title_static_sharing">Udostępnij lokalizację</string> + <string name="closed_poll_option_description">Wyniki są ujawniane dopiero po zakończeniu ankiety</string> + <string name="closed_poll_option_title">Ankieta zamknięta</string> + <string name="open_poll_option_description">Głosujący widzą wyniki zaraz po oddaniu głosu</string> + <string name="open_poll_option_title">Otwarta ankieta</string> + <string name="poll_type_title">Rodzaj ankiety</string> + <string name="edit_poll_title">Modyfikacja ankiety</string> + <string name="a11y_poll_winner_option">opcja zwyciężająca</string> + <string name="poll_no_votes_cast">Brak głosów</string> + <string name="this_invite_to_this_space_was_sent">Zaproszenie do tej przestrzeni zostało wysłane do %s, które nie jest powiązane z Twoim kontem</string> + <string name="this_invite_to_this_room_was_sent">Zaproszenie do tego pokoju zostało wysłane do %s, które nie jest powiązane z Twoim kontem</string> + <string name="upgrade_room_for_restricted_no_param">Każdy w przestrzeni nadrzędnej będzie mógł znaleźć ten pokój i dołączyć do niego — nie ma potrzeby ręcznego zapraszania wszystkich. W każdej chwili możesz to zmienić w ustawieniach pokoju.</string> + <string name="upgrade_room_update_parent_space">Automatycznie aktualizuj nadrzędną przestrzeń</string> + <string name="labs_auto_report_uisi_desc">Twój system automatycznie wyśle dzienniki, gdy wystąpi błąd niemożności odszyfrowania</string> + <string name="labs_auto_report_uisi">Błędy automatycznego deszyfrowania raportów.</string> + <string name="command_description_leave_room">Opuść pokój o podanym identyfikatorze (lub aktualny pokój, jeśli null)</string> + <string name="sent_location">Udostępnili swoją lokalizację</string> + <string name="room_message_notify_everyone">Powiadom cały pokój</string> + <string name="room_message_autocomplete_users">Użytkownicy</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-pt-rBR/strings.xml b/vector/src/main/res/values-pt-rBR/strings.xml index d06937fb64..f682a123f4 100644 --- a/vector/src/main/res/values-pt-rBR/strings.xml +++ b/vector/src/main/res/values-pt-rBR/strings.xml @@ -1953,11 +1953,11 @@ <item quantity="other">%d entradas</item> </plurals> <string name="settings_server_upload_size_title">Limite de upload de arquivo do servidor</string> - <string name="room_settings_room_access_restricted_description">Qualquer pessoa num espaço com esta sala pode encontrá-la e juntar-se a ela. Somente admins desta sala podem adicioná-la a um espaço.</string> + <string name="room_settings_room_access_restricted_description">Qualquer pessoa num espaço com esta sala pode achá-la e se juntar a ela. Somente admins desta sala podem adicioná-la a um espaço.</string> <string name="room_settings_room_access_restricted_title">Membros de espaço somente</string> - <string name="room_settings_room_access_public_description">Qualquer pessoa pode encontrar a sala e juntar-se</string> + <string name="room_settings_room_access_public_description">Qualquer pessoa pode achar a sala e se juntar</string> <string name="room_settings_room_access_public_title">Pública</string> - <string name="room_settings_room_access_private_description">Somente pessoas convidadas podem encontrar e juntar-se</string> + <string name="room_settings_room_access_private_description">Somente pessoas convidadas podem achar e se juntar</string> <string name="room_settings_room_access_private_title">Privada</string> <string name="room_settings_room_access_entry_unknown">Configuração de acesso desconhecida (%s)</string> <string name="room_settings_room_access_entry_knock">Qualquer pessoa pode tocar na sala, membros podem então aceitar ou rejeitar</string> @@ -2024,7 +2024,7 @@ <item quantity="other">%d pessoas que você conhece já têm se juntado</item> </plurals> <string name="join_space">Juntar-Se a Espaço</string> - <string name="create_space">Criar Espaço</string> + <string name="create_space">Criar espaço</string> <string name="share_space_link_message">Junte-se a meu espaço %1$s %2$s</string> <string name="invite_to_space_with_name_desc">Elas vão ser capazes de explorar %s</string> <string name="invite_to_space_with_name">Convidar para %s</string> @@ -2058,7 +2058,7 @@ <string name="create_spaces_choose_type_label">Que tipo de espaço você quer criar\?</string> <string name="your_private_space">Seu espaço privado</string> <string name="your_public_space">Seu espaço público</string> - <string name="add_space">Adicionar Espaço</string> + <string name="add_space">Adicionar espaço</string> <string name="private_space">Espaço privado</string> <string name="public_space">Espaço público</string> <string name="command_description_create_space">Criar um Espaço</string> @@ -2111,8 +2111,8 @@ <item quantity="other">%d chamadas de áudio perdidas</item> </plurals> <string name="upgrade_room_for_restricted_note">Por favor note que fazer upgrade vai fazer uma nova versão da sala. Todas as mensagens atuais vão permanecer nesta sala arquivada.</string> - <string name="upgrade_room_for_restricted_no_param">Qualquer pessoa em um espaço pai vai ser capaz de encontrar e juntar-se a esta sala - não precisa convidar manualmente todo mundo. Você vai ser capaz de mudar isto em configurações de sala a qualquer hora.</string> - <string name="upgrade_room_for_restricted">Qualquer pessoa em %s vai ser capaz de encontrar e juntar-se a esta sala - não precisa convidar todo mundo. Você vai ser capaz de mudar isto em configurações de sala a qualquer hora.</string> + <string name="upgrade_room_for_restricted_no_param">Qualquer pessoa em um espaço pai vai ser capaz de achar e se juntar a esta sala - não precisa convidar manualmente todo mundo. Você vai ser capaz de mudar isto em configurações de sala a qualquer hora.</string> + <string name="upgrade_room_for_restricted">Qualquer pessoa em %s vai ser capaz de achar e se juntar a esta sala - não precisa convidar todo mundo. Você vai ser capaz de mudar isto em configurações de sala a qualquer hora.</string> <string name="voice_message_reply_content">Mensagem de Voz (%1$s)</string> <string name="error_voice_message_cannot_reply_or_edit">Não dá para responder ou editar enquanto mensagem de voz está ativa</string> <string name="error_voice_message_unable_to_record">Não dá para gravar uma mensagem de voz</string> @@ -2130,13 +2130,13 @@ <string name="sent_a_voice_message">Voz</string> <string name="other_spaces_or_rooms_you_might_not_know">Outros espaços ou salas que você poderia não saber</string> <string name="space_you_know_that_contains_this_room">Espaço que você sabe que contém esta sala</string> - <string name="decide_who_can_find_and_join">Decida quem pode encontrar e juntar-se a esta sala.</string> + <string name="decide_who_can_find_and_join">Decida quem pode achar e se juntar a esta sala.</string> <string name="tap_to_edit_spaces">Toque para editar espaços</string> <string name="select_spaces">Selecionar espaços</string> - <string name="decide_which_spaces_can_access">Decida que espaços podem acessar esta sala. Se um espaço é selecionado seus membros vão ser capazes de encontrar e juntar-se a Nome de sala.</string> + <string name="decide_which_spaces_can_access">Decida que espaços podem acessar esta sala. Se um espaço é selecionado seus membros vão ser capazes de achar e se juntar a Nome de sala.</string> <string name="spaces_which_can_access">Espaços que podem acessar</string> <string name="allow_space_member_to_find_and_access">Permitir membros de espaço a encontrar e acessar.</string> - <string name="room_create_member_of_space_name_can_join">Membros de Escpaço %s podem encontrar, previsualizar e juntar-se.</string> + <string name="room_create_member_of_space_name_can_join">Membros de Espaço %s podem achar, previsualizar e se juntar.</string> <string name="room_settings_room_access_private_invite_only_title">Privada (Convite Somente)</string> <string name="denied_permission_voice_message">Para enviar mensagens de voz, por favor conceda a permissão Microfone.</string> <string name="settings_notification_notify_me_for">Notifique-me para</string> @@ -2222,7 +2222,7 @@ <string name="open_discovery_settings">Abrir Configurações de Descoberta</string> <string name="user_directory_search_hint_2">Pesquisar por nome, ID ou mail</string> <string name="create_new_space">Criar Novo Espaço</string> - <string name="room_settings_space_access_public_description">Qualquer pessoa pode encontrar o espaço e se juntar</string> + <string name="room_settings_space_access_public_description">Qualquer pessoa pode achar o espaço e se juntar</string> <string name="room_settings_space_access_title">Acesso a espaço</string> <string name="room_settings_access_rules_pref_dialog_title">Quem pode acessar\?</string> <string name="settings_notification_emails_enable_for_email">Habilitar notificações de email para %s</string> @@ -2392,7 +2392,7 @@ <string name="command_not_supported_in_threads">O comando \"%s\" é reconhecido mas não suportado em threads.</string> <string name="search_thread_from_a_thread">De uma Thread</string> <string name="thread_list_empty_notice">Dica: Toque longo numa mensagem e use “%s”.</string> - <string name="thread_list_empty_subtitle">Threads ajudam a manter suas conversas em-tópico e fáceis de rastrear.</string> + <string name="thread_list_empty_subtitle">Threads ajudam manter suas conversas em-tópico e fáceis de rastrear.</string> <string name="thread_list_empty_title">Mantenha discussões organizadas com threads</string> <string name="thread_list_modal_my_threads_subtitle">Mostra todas as threads nas quais você tem participado</string> <string name="thread_list_modal_my_threads_title">Minhas Threads</string> @@ -2438,4 +2438,23 @@ \n \nIsto vai ser uma transição única visto que Threads são agora parte da especificação Matrix.</string> <string name="threads_notice_migration_title">Threads Aproximando-Se a Beta 🎉</string> + <string name="live_location_sharing_notification_title">${app_name} Localização ao Vivo</string> + <string name="live_location_sharing_notification_description">Compartilhamento de localização está em progresso</string> + <string name="error_forbidden_digits_only_username">O servidorcasa não aceita nome de usuária(o) com somente dígitos.</string> + <string name="ftue_personalize_skip_this_step">Pular este passo</string> + <string name="ftue_personalize_submit">Salvar e continuar</string> + <string name="ftue_personalize_complete_subtitle">Suas preferências têm sido salvas.</string> + <string name="ftue_personalize_complete_title">Você está pronta(o)!</string> + <string name="ftue_personalize_lets_go">Vamo lá</string> + <string name="ftue_profile_picture_subtitle">Você pode mudar isto a qualquer hora.</string> + <string name="ftue_profile_picture_title">Adicione uma imagem de perfil</string> + <string name="ftue_display_name_entry_footer">Você pode mudar isto mais tarde</string> + <string name="ftue_display_name_entry_title">Nome de Exibição</string> + <string name="ftue_display_name_subtitle">Isto vai ser mostrado quando você enviar mensagens.</string> + <string name="ftue_display_name_title">Escolha um nome de exibição</string> + <string name="ftue_account_created_subtitle">Sua conta %s tem sido criada.</string> + <string name="ftue_account_created_congratulations_title">Parabéns!</string> + <string name="ftue_account_created_take_me_home">Me leve para casa</string> + <string name="ftue_account_created_personalize">Personalizar perfil</string> + <string name="action_disable">Desabilitar</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-sk/strings.xml b/vector/src/main/res/values-sk/strings.xml index bd3e86e40c..ff1089caa0 100644 --- a/vector/src/main/res/values-sk/strings.xml +++ b/vector/src/main/res/values-sk/strings.xml @@ -129,8 +129,8 @@ <string name="power_level_default">Predvolený</string> <string name="power_level_custom">Vlastná úroveň (%1$d)</string> <string name="power_level_custom_no_value">Vlastná úroveň</string> - <string name="notice_power_level_changed_by_you">Zmenili ste úroveň moci používateľa %1$s.</string> - <string name="notice_power_level_changed">%1$s zmenil úroveň moci používateľa %2$s.</string> + <string name="notice_power_level_changed_by_you">Zmenili ste úroveň oprávnenia používateľa %1$s.</string> + <string name="notice_power_level_changed">%1$s zmenil úroveň oprávnenia používateľa %2$s.</string> <string name="notice_power_level_diff">%1$s z %2$s na %3$s</string> <string name="notice_room_invite_no_invitee_with_reason_by_you">Pozvanie od vás. Dôvod: %1$s</string> <string name="notice_room_invite_with_reason_by_you">Pozvali ste %1$s. Dôvod: %2$s</string> @@ -284,7 +284,7 @@ <string name="room_participants_action_ignore">Skryť všetky správy od tohoto používateľa</string> <string name="room_participants_action_unignore">Zobraziť všetky správy od tohoto používateľa</string> <string name="room_participants_action_mention">Zmieniť sa</string> - <string name="room_participants_power_level_prompt">Túto zmenu nebudete môcť vrátiť späť, pretože tomuto používateľovi udeľujete rovnakú úroveň moci, akú máte vy. + <string name="room_participants_power_level_prompt">Túto zmenu nebudete môcť vrátiť späť, pretože tomuto používateľovi udeľujete rovnakú úroveň oprávnenia, akú máte vy. \nSte si istí\?</string> <string name="room_one_user_is_typing">%s píše…</string> <string name="room_two_users_are_typing">%1$s a %2$s píšu…</string> @@ -427,7 +427,7 @@ <string name="widget_delete_message_confirmation">Ste si istí, že chcete odstrániť widget z tejto miestnosti?</string> <string name="widget_integration_unable_to_create">Nie je možné vytvoriť widget.</string> <string name="widget_integration_failed_to_send_request">Nepodarilo sa odoslať požiadavku.</string> - <string name="widget_integration_positive_power_level">Úroveň moci musí byť kladné celé číslo.</string> + <string name="widget_integration_positive_power_level">Úroveň oprávnenia musí byť kladné celé číslo.</string> <string name="widget_integration_must_be_in_room">Nenachádzate sa v tejto miestnosti.</string> <string name="widget_integration_no_permission_in_room">V tejto miestnosti nemáte oprávnenie na vykonanie takejto akcie.</string> <string name="widget_integration_missing_room_id">V požiadavke chýba room_id.</string> @@ -536,8 +536,8 @@ <string name="command_description_emote">Zobrazí akciu</string> <string name="command_description_ban_user">Zakáže vstup zadanému používateľovi</string> <string name="command_description_unban_user">Povolí vstup zadanému používateľovi</string> - <string name="command_description_op_user">Určuje úroveň moci pre zadaného používateľa</string> - <string name="command_description_deop_user">Znižuje úroveň moci pre zadaného používateľa</string> + <string name="command_description_op_user">Určuje úroveň oprávnenia pre zadaného používateľa</string> + <string name="command_description_deop_user">Odstráni používateľa s daným ID</string> <string name="command_description_invite_user">Pozve zadaného používateľa do aktuálnej miestnosti</string> <string name="command_description_join_room">Pripojí sa do miestnosti s danou adresou</string> <string name="command_description_part_room">Opustí aktuálnu miestnosť</string> @@ -667,7 +667,7 @@ <string name="settings_troubleshoot_test_fcm_failed_too_many_registration">[%1$s] \nNa zariadení máte množstvo aplikácií zaregistrovaných na doručovanie okamžitých oznámení cez služby Google play. Konfigurácia ${app_name} nemá vplyv na výskyt tejto chyby. Podľa Google sa môže vyskytovať len pri veľmi vysokom počte nainštalovaných aplikácií. Bežní používatelia by týmto nemali byť postihnutí.</string> <string name="settings_troubleshoot_test_fcm_failed_service_not_available">[%1$s] -\nKonfigurácia ${app_name} nemá vplyv na zobrazenie tejto chyby. Táto chyba sa môže zobraziť z niekoľkých dôvodov. Uistite sa že máte správne nastavený systémový čas a že ste v nastaveniach systému aplikácii služby Google play neobmedzili používanie prístupu na internet. Chyba sa tiež môže zobrazovať na vlastných zostaveniach (ROM), alebo sa chyba môže samovoľne prestať zobrazovať neskôr.</string> +\nTáto chyba sa vymkla spod kontroly aplikácie ${app_name}. Môže sa vyskytnúť z niekoľkých dôvodov. Možno to bude fungovať, ak to neskôr skúsite znova, môžete tiež skontrolovať, či služba Google Play nemá v systémových nastaveniach obmedzené používanie dát, alebo či sú hodiny vášho zariadenia správne, prípadne sa to môže stať na vlastnej ROM.</string> <string name="settings_troubleshoot_test_fcm_failed_account_missing">[%1$s] \nV zariadení nemáte nastavený účet Google. Prosím, pridajte si účet cez správcu účtov. Konfigurácia ${app_name} nemá vplyv na zobrazenie tejto chyby.</string> <string name="settings_troubleshoot_test_fcm_failed_account_missing_quick_fix">Pridať účet</string> @@ -743,8 +743,8 @@ <string name="settings_call_show_confirmation_dialog_title">Zabrániť neúmyselnému telefonovaniu</string> <string name="settings_call_show_confirmation_dialog_summary">Žiadať potvrdenie pred uskutočnením hovoru</string> <string name="room_participants_action_cancel_invite">Zrušiť pozvanie</string> - <string name="room_participants_power_level_demote_warning_title">Znížiť vlastnú úroveň moci\?</string> - <string name="room_participants_power_level_demote_warning_prompt">Túto zmenu nebudete môcť vrátiť späť, pretože znižujete vašu vlastnú úroveň moci. Ak ste jediný poverený používateľ v miestnosti, nebudete môcť znovu získať úroveň, akú máte teraz.</string> + <string name="room_participants_power_level_demote_warning_title">Znížiť vlastnú úroveň oprávnenia\?</string> + <string name="room_participants_power_level_demote_warning_prompt">Túto zmenu nebudete môcť vrátiť späť, pretože znižujete vašu vlastnú úroveň oprávnenia. Ak ste jediný poverený používateľ v miestnosti, nebudete môcť znovu získať úroveň, akú máte teraz.</string> <string name="room_participants_power_level_demote">Znížiť</string> <string name="room_participants_action_ignore_title">Ignorovať používateľa</string> <string name="room_participants_action_ignore_prompt_msg">Ignorovaním tohoto používateľa odstránite všetky jeho správy vo vašich spoločných miestnostiach. @@ -900,7 +900,7 @@ <plurals name="keys_backup_restore_success_description_part1"> <item quantity="one">Záloha s %d kľúčom obnovená.</item> <item quantity="few">Záloha s %d kľúčmi obnovená.</item> - <item quantity="other">Záloha s %d kľúčami obnovená.</item> + <item quantity="other">Záloha s %d kľúčmi obnovená.</item> </plurals> <plurals name="keys_backup_restore_success_description_part2"> <item quantity="one">%d nový kľúč bol pridaný do tejto relácie.</item> @@ -1005,7 +1005,7 @@ <string name="push_gateway_item_url">Url:</string> <string name="push_gateway_item_format">Formát:</string> <string name="preference_voice_and_video">Zvuk a video</string> - <string name="preference_root_help_about">Pomoc a O aplikácii</string> + <string name="preference_root_help_about">Pomoc a o aplikácii</string> <string name="settings_troubleshoot_test_token_registration_quick_fix">Zaregistrovať token</string> <string name="send_suggestion">Poslať návrh</string> <string name="send_suggestion_content">Nižšie napíšte obsah návrhu.</string> @@ -1652,8 +1652,8 @@ <string name="verification_no_scan_emoji_title">Overiť porovnaním emotikonov</string> <string name="verification_scan_self_emoji_subtitle">Namiesto toho overte porovnaním emotikonov</string> <string name="verification_scan_emoji_subtitle">Ak nie ste osobne, porovnajte namiesto toho emotikony</string> - <string name="verification_scan_with_this_device">Skenovať pomocou tohto zariadenia</string> - <string name="verification_scan_self_notice">Naskenujte kód pomocou iného zariadenia alebo prepnite a skenujte pomocou tohto zariadenia</string> + <string name="verification_scan_with_this_device">Naskenovať pomocou tohto zariadenia</string> + <string name="verification_scan_self_notice">Naskenujte kód pomocou iného zariadenia alebo prepnite a naskenujte pomocou tohto zariadenia</string> <string name="verification_scan_notice">Naskenujte kód pomocou zariadenia druhého používateľa, aby ste sa navzájom bezpečne overili</string> <string name="sent_verification_conclusion">Záver overovania</string> <string name="verification_conclusion_compromised">Môže byť narušená jedna z nasledujúcich vecí: @@ -2485,4 +2485,23 @@ \n \nPôjde o jednorazový prechod, keďže vlákna sú teraz súčasťou špecifikácie Matrix.</string> <string name="threads_notice_migration_title">Vlákna sa blížia k beta verzii 🎉</string> + <string name="ftue_account_created_subtitle">Váš účet %s bol vytvorený.</string> + <string name="live_location_sharing_notification_description">Prebieha zdieľanie polohy</string> + <string name="live_location_sharing_notification_title">${app_name} Poloha v reálnom čase</string> + <string name="error_forbidden_digits_only_username">Domovský server neakceptuje používateľské meno obsahujúce iba číslice.</string> + <string name="ftue_personalize_skip_this_step">Vynechať tento krok</string> + <string name="ftue_personalize_submit">Uložiť a pokračovať</string> + <string name="ftue_personalize_complete_subtitle">Vaše nastavenia boli uložené.</string> + <string name="ftue_personalize_complete_title">Všetko je pripravené!</string> + <string name="ftue_personalize_lets_go">Poďme na to</string> + <string name="ftue_profile_picture_subtitle">Toto môžete kedykoľvek zmeniť.</string> + <string name="ftue_profile_picture_title">Pridať profilový obrázok</string> + <string name="ftue_display_name_entry_footer">Neskôr to môžete zmeniť</string> + <string name="ftue_display_name_entry_title">Zobrazované meno</string> + <string name="ftue_display_name_subtitle">Toto sa zobrazí pri odosielaní správ.</string> + <string name="ftue_display_name_title">Vyberte si zobrazované meno</string> + <string name="ftue_account_created_congratulations_title">Gratulujeme!</string> + <string name="ftue_account_created_take_me_home">Zober ma domov</string> + <string name="ftue_account_created_personalize">Prispôsobiť profil</string> + <string name="action_disable">Zakázať</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-sq/strings.xml b/vector/src/main/res/values-sq/strings.xml index fb7fb1448e..ddb492016c 100644 --- a/vector/src/main/res/values-sq/strings.xml +++ b/vector/src/main/res/values-sq/strings.xml @@ -1957,7 +1957,7 @@ \nRiprovoni më vonë, ose kërkojini një përgjegjësi dhome të kontrollojë nëse keni leje për hyrje.</string> <string name="join_anyway">Hyni, Sido Qoftë</string> <string name="join_space">Hyni te Hapësirë</string> - <string name="create_space">Krijo Hapësirën</string> + <string name="create_space">Krijo hapësirën</string> <string name="skip_for_now">Hëpërhë anashkaloje</string> <string name="share_space_link_message">Ejani në hapësirën time %1$s %2$s</string> <string name="invite_just_to_this_room_desc">S’do të jenë pjesë e %s</string> @@ -1996,7 +1996,7 @@ <string name="create_spaces_choose_type_label">Ç’lloj hapësire doni të krijoni\?</string> <string name="your_private_space">Hapësira juaj private</string> <string name="your_public_space">Hapësira juaj publike</string> - <string name="add_space">Shtoni Hapësirë</string> + <string name="add_space">Shtoni hapësirë</string> <string name="command_description_leave_room">Braktiseni dhomën me ID-në e dhënë (ose dhomën e tanishme, në qoftë nul)</string> <string name="command_description_join_space">Hyni te Hapësira me ID-në e dhënë</string> <string name="command_description_create_space">Krijoni një Hapësirë</string> @@ -2425,4 +2425,24 @@ \n \nKy do të jetë tranzicion vetëm për një herë, meqë tanimë Rrjedhat janë pjesë e protokollit Matrix.</string> <string name="threads_notice_migration_title">Rrjedhat Po i Afrohen Beta-s 🎉</string> + <string name="live_location_sharing_notification_description">Tregimi i vendndodhjes është në punë e sipër</string> + <string name="a11y_location_share_option_user_live_icon">Jepe vendndodhjen “live”</string> + <string name="location_share_option_user_live">Jepe vendndodhjen “live”</string> + <string name="error_forbidden_digits_only_username">Shërbyesi Home s’pranon emër përdorues vetëm me shifra.</string> + <string name="ftue_personalize_skip_this_step">Anashkalojeni këtë hap</string> + <string name="ftue_personalize_submit">Ruajeni dhe vazhdoni</string> + <string name="ftue_personalize_complete_subtitle">Parapëlqimet tuaja u ruajtën.</string> + <string name="ftue_personalize_complete_title">Kaq qe!</string> + <string name="ftue_personalize_lets_go">Shkojmë</string> + <string name="ftue_profile_picture_subtitle">Këtë mund ta ndryshoni kurdo.</string> + <string name="ftue_profile_picture_title">Shtoni një foto profili</string> + <string name="ftue_display_name_entry_footer">Këtë mund ta ndryshoni më vonë</string> + <string name="ftue_display_name_entry_title">Emër Në Ekran</string> + <string name="ftue_display_name_subtitle">Kjo do të shfaqet kur dërgoni mesazhe.</string> + <string name="ftue_display_name_title">Zgjidhni një emër për në ekran</string> + <string name="ftue_account_created_subtitle">Llogaria juaj %s u krijua.</string> + <string name="ftue_account_created_congratulations_title">Përgëzime!</string> + <string name="ftue_account_created_take_me_home">Shpjemëni në shtëpi</string> + <string name="ftue_account_created_personalize">Personalizoni profil</string> + <string name="action_disable">Çaktivizoje</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-sv/strings.xml b/vector/src/main/res/values-sv/strings.xml index 2b4e3502f8..c6c8b45441 100644 --- a/vector/src/main/res/values-sv/strings.xml +++ b/vector/src/main/res/values-sv/strings.xml @@ -2438,4 +2438,23 @@ \nMedan vi förbereder den så behöver vi göra några ändringar: trådar skapade innan den här tidpunkten kommer att visas som vanliga svar. \n \nDet kommer att vara en engångshändelse, eftersom trådar nu är en del av Matrixspecifikationen.</string> + <string name="live_location_sharing_notification_description">Platsdelning pågår</string> + <string name="live_location_sharing_notification_title">${app_name} Kontinuerlig plats</string> + <string name="error_forbidden_digits_only_username">Hemservern accepterar inte användarnamn med bara siffror.</string> + <string name="ftue_personalize_skip_this_step">Hoppa över det här steget</string> + <string name="ftue_personalize_submit">Spara och fortsätt</string> + <string name="ftue_personalize_complete_subtitle">Dina inställningar har sparats.</string> + <string name="ftue_personalize_complete_title">Du är redo!</string> + <string name="ftue_personalize_lets_go">Nu kör vi</string> + <string name="ftue_profile_picture_subtitle">Du kan ändra detta när som helst.</string> + <string name="ftue_profile_picture_title">Lägg till en profilbild</string> + <string name="ftue_display_name_entry_footer">Du kan ändra detta senare</string> + <string name="ftue_display_name_entry_title">Visningsnamn</string> + <string name="ftue_display_name_subtitle">Det här kommer att visas när du skickar meddelanden.</string> + <string name="ftue_display_name_title">Välj ett visningsnamn</string> + <string name="ftue_account_created_subtitle">Ditt konto %s har skapats.</string> + <string name="ftue_account_created_congratulations_title">Grattis!</string> + <string name="ftue_account_created_take_me_home">För mig hem</string> + <string name="ftue_account_created_personalize">Anpassa profil</string> + <string name="action_disable">Inaktivera</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-uk/strings.xml b/vector/src/main/res/values-uk/strings.xml index 26d090e3ef..ce1781cb9c 100644 --- a/vector/src/main/res/values-uk/strings.xml +++ b/vector/src/main/res/values-uk/strings.xml @@ -1490,7 +1490,7 @@ <string name="room_settings_room_access_entry_unknown">Невідоме налаштування доступу (%s)</string> <string name="room_settings_room_access_entry_knock">Будь-хто може попроситися до кімнати, учасники можуть прийняти або відхилити</string> <string name="join_anyway">Усе одно приєднатися</string> - <string name="create_space">Створити Простір</string> + <string name="create_space">Створити простір</string> <string name="join_space">Приєднатися до Простору</string> <string name="invite_by_link">Поділитися посиланням</string> <string name="invite_by_email">Запросити електронним листом</string> @@ -2530,4 +2530,23 @@ \n \nЦе буде одноразовий перехід, оскільки треди — тепер частина специфікації Matrix.</string> <string name="threads_notice_migration_title">Незабаром бета-версія тредів 🎉</string> + <string name="live_location_sharing_notification_description">Триває передавання місцеперебування</string> + <string name="live_location_sharing_notification_title">${app_name} Місцеперебування наживо</string> + <string name="error_forbidden_digits_only_username">Домашній сервер не приймає ім\'я користувача лише з цифр.</string> + <string name="ftue_personalize_skip_this_step">Пропустити цей крок</string> + <string name="ftue_personalize_submit">Зберегти й продовжити</string> + <string name="ftue_personalize_complete_subtitle">Ваші налаштування збережено.</string> + <string name="ftue_personalize_complete_title">Усе налаштовано!</string> + <string name="ftue_personalize_lets_go">Поїхали</string> + <string name="ftue_profile_picture_subtitle">Ви можете змінити його будь-коли.</string> + <string name="ftue_profile_picture_title">Додати зображення профілю</string> + <string name="ftue_display_name_entry_footer">Ви можете змінити його пізніше</string> + <string name="ftue_display_name_entry_title">Показуване ім\'я</string> + <string name="ftue_display_name_subtitle">Його буде показано у надісланих повідомленнях.</string> + <string name="ftue_display_name_title">Виберіть показуване ім\'я</string> + <string name="ftue_account_created_subtitle">Ваш обліковий запис %s створено.</string> + <string name="ftue_account_created_congratulations_title">Вітаємо!</string> + <string name="ftue_account_created_take_me_home">На головну</string> + <string name="ftue_account_created_personalize">Персоналізувати профіль</string> + <string name="action_disable">Вимкнути</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values-zh-rTW/strings.xml b/vector/src/main/res/values-zh-rTW/strings.xml index 781591ace7..ea0c677168 100644 --- a/vector/src/main/res/values-zh-rTW/strings.xml +++ b/vector/src/main/res/values-zh-rTW/strings.xml @@ -2391,4 +2391,23 @@ \n \n這會是一次性的過渡,因為討論串現在是 Matrix 規範的一部分了。</string> <string name="threads_notice_migration_title">討論串接近測試版了 🎉</string> + <string name="live_location_sharing_notification_description">正在進行位置分享</string> + <string name="live_location_sharing_notification_title">${app_name} 即時位置</string> + <string name="error_forbidden_digits_only_username">家伺服器不接受僅有數字的使用者名稱。</string> + <string name="ftue_personalize_skip_this_step">略過此步驟</string> + <string name="ftue_personalize_submit">儲存並繼續</string> + <string name="ftue_personalize_complete_subtitle">您的偏好設定已儲存。</string> + <string name="ftue_personalize_complete_title">準備好了!</string> + <string name="ftue_personalize_lets_go">走吧</string> + <string name="ftue_profile_picture_subtitle">您可以在任何時候變更這個。</string> + <string name="ftue_profile_picture_title">新增個人資訊照片</string> + <string name="ftue_display_name_entry_footer">您可以在稍後變更這個</string> + <string name="ftue_display_name_entry_title">顯示名稱</string> + <string name="ftue_display_name_subtitle">這將會在您傳送訊息時顯示。</string> + <string name="ftue_display_name_title">選擇顯示名稱</string> + <string name="ftue_account_created_subtitle">您的帳號 %s 已建立。</string> + <string name="ftue_account_created_congratulations_title">恭喜!</string> + <string name="ftue_account_created_take_me_home">帶我回家</string> + <string name="ftue_account_created_personalize">個人化檔案</string> + <string name="action_disable">停用</string> </resources> \ No newline at end of file diff --git a/vector/src/main/res/values/donottranslate.xml b/vector/src/main/res/values/donottranslate.xml index 48d2950cd5..221a80e6b3 100755 --- a/vector/src/main/res/values/donottranslate.xml +++ b/vector/src/main/res/values/donottranslate.xml @@ -17,7 +17,18 @@ <string name="ftue_auth_create_account_choose_server_header">Choose your server to store your data</string> <string name="ftue_auth_create_account_sso_section_header">Or</string> <string name="ftue_auth_create_account_matrix_dot_org_server_description">Join millions for free on the largest public server</string> - <string name="ftue_auth_create_account_matrix_dot_org_server_name">matrix.org</string> <string name="ftue_auth_create_account_edit_server_selection">Edit</string> + <string name="ftue_auth_choose_server_title">Choose your server</string> + <string name="ftue_auth_choose_server_subtitle">What is the address of your server? Server is like a home for all your data.</string> + <string name="ftue_auth_choose_server_entry_hint">Server URL</string> + <string name="ftue_auth_choose_server_entry_footer">You can only connect to a server that has already been set up</string> + <string name="ftue_auth_choose_server_ems_title">Want to host your own server?</string> + + <string name="ftue_auth_choose_server_ems_subtitle">Element Matrix Services (EMS) is a robust and reliable hosting service for fast, secure and real time communication. Find out how on <a href="${ftue_ems_url}">element.io/ems</a></string> + <string name="ftue_auth_choose_server_ems_cta">Get in touch</string> + + <string name="ftue_auth_terms_title">Privacy policy</string> + <string name="ftue_auth_terms_subtitle">Please read through T&C. You must accept in order to continue.</string> + </resources> diff --git a/vector/src/main/res/values/strings.xml b/vector/src/main/res/values/strings.xml index 0ab450421c..d849c1a58a 100644 --- a/vector/src/main/res/values/strings.xml +++ b/vector/src/main/res/values/strings.xml @@ -634,7 +634,7 @@ <string name="room_participants_action_ignore">Ignore</string> <string name="room_participants_action_unignore_title">Unignore user</string> - <string name="room_participants_action_unignore_prompt_msg">Unignoring this user will show all messages from them again.</string> + <string name="room_participants_action_unignore_prompt_msg">Unignoring this user will show all messages from them again.\n\nNote that this action will restart the app and it may take some time.</string> <string name="room_participants_action_unignore">Unignore</string> <string name="room_participants_action_cancel_invite_title">Cancel invite</string> @@ -739,6 +739,9 @@ <string name="threads_beta_enable_notice_title">Threads Beta</string> <!-- %s will be replaced with action_learn_more string resource that will be clickable(url redirection) --> <string name="threads_beta_enable_notice_message">Threads help keep your conversations on-topic and easy to track. %sEnabling threads will refresh the app. This may take longer for some accounts.</string> + <string name="threads_labs_enable_notice_title">Threads Beta</string> + <string name="threads_labs_enable_notice_message">Your homeserver does not currently support threads, so this feature may be unreliable. Some threaded messages may not be reliably available. %sDo you want to enable threads anyway?</string> + <!-- Search --> <string name="search_hint">Search</string> @@ -1056,6 +1059,11 @@ <string name="media_saving_period_1_month">1 month</string> <string name="media_saving_period_forever">Forever</string> + <!-- Presence settings --> + <string name="settings_presence">Presence</string> + <string name="settings_presence_user_always_appears_offline">Offline mode</string> + <string name="settings_presence_user_always_appears_offline_summary">If enabled, you will always appear offline to other users, even when using the application.</string> + <!-- Room Settings --> <!-- room global settings--> @@ -1655,7 +1663,8 @@ <string name="you_may_contact_me">You may contact me if you have any follow up questions</string> <string name="feedback_sent">Thanks, your feedback has been successfully sent</string> <string name="feedback_failed">The feedback failed to be sent (%s)</string> - <string name="give_feedback">Give Feedback</string> + <!-- TODO TO BE REMOVED --> + <string name="give_feedback" tools:ignore="UnusedResources">Give Feedback</string> <string name="give_feedback_threads">Give Feedback</string> <string name="send_feedback_threads_title">Threads Beta feedback</string> <string name="send_feedback_threads_info">Threads are a work in progress with new, exciting upcoming features, such as improved notifications. We’d love to hear your feedback!</string> @@ -1862,7 +1871,7 @@ <string name="ftue_auth_carousel_control_body">Choose where your conversations are kept, giving you control and independence. Connected via Matrix.</string> <string name="ftue_auth_carousel_encrypted_body">End-to-end encrypted and no phone number required. No ads or datamining.</string> <!-- Note to translators: the translation MUST contain the string "${app_name}", which will be replaced by the application name --> - <string name="ftue_auth_carousel_workplace_body" translatable="false">${app_name} is also great for the workplace. It’s trusted by the world’s most secure organisations.</string> + <string name="ftue_auth_carousel_workplace_body">${app_name} is also great for the workplace. It’s trusted by the world’s most secure organisations.</string> <string name="ftue_auth_use_case_title">Who will you chat to the most?</string> <string name="ftue_auth_use_case_subtitle">We\'ll help you get connected.</string> @@ -2116,6 +2125,7 @@ <string name="sent_a_reaction">Reacted with: %s</string> <string name="sent_verification_conclusion">Verification Conclusion</string> <string name="sent_location">Shared their location</string> + <string name="sent_live_location">Shared their live location</string> <string name="verification_request_waiting">Waiting…</string> <string name="verification_request_other_cancelled">%s cancelled</string> @@ -2892,6 +2902,14 @@ <string name="error_voice_message_cannot_reply_or_edit">Cannot reply or edit while voice message is active</string> <string name="voice_message_reply_content">Voice Message (%1$s)</string> + <string name="a11y_audio_message_item">%1$s, %2$s, %3$s</string> <!-- filename, duration, file size --> + <string name="a11y_audio_playback_duration">%1$d minutes %2$d seconds</string> + <string name="a11y_play_audio_message">Play %1$s</string> + <string name="a11y_pause_audio_message">Pause %1$s</string> + <string name="error_audio_message_unable_to_play">Unable to play %1$s</string> + <string name="audio_message_reply_content">%1$s (%2$s)</string> + <string name="audio_message_file_size">(%1$s)</string> + <string name="upgrade_room_for_restricted">Anyone in %s will be able to find and join this room - no need to manually invite everyone. You’ll be able to change this in room settings anytime.</string> <string name="upgrade_room_for_restricted_no_param">Anyone in a parent space will be able to find and join this room - no need to manually invite everyone. You’ll be able to change this in room settings anytime.</string> @@ -2985,6 +3003,7 @@ <string name="labs_render_locations_in_timeline">Render user locations in the timeline</string> <string name="location_timeline_failed_to_load_map">Failed to load map</string> <string name="location_share_live_enabled">Live location enabled</string> + <string name="location_share_live_started">Loading live location…</string> <string name="location_share_live_stop">Stop</string> <string name="live_location_sharing_notification_title">${app_name} Live Location</string> <string name="live_location_sharing_notification_description">Location sharing is in progress</string> diff --git a/vector/src/main/res/xml/vector_settings_preferences.xml b/vector/src/main/res/xml/vector_settings_preferences.xml index ec4c6d5e48..25647845bf 100644 --- a/vector/src/main/res/xml/vector_settings_preferences.xml +++ b/vector/src/main/res/xml/vector_settings_preferences.xml @@ -303,6 +303,18 @@ </im.vector.app.core.preference.VectorPreferenceCategory> + <im.vector.app.core.preference.VectorPreferenceCategory + android:title="@string/settings_presence" + app:isPreferenceVisible="@bool/settings_presence_visible"> + + <im.vector.app.core.preference.VectorSwitchPreference + android:title="@string/settings_presence_user_always_appears_offline" + android:summary="@string/settings_presence_user_always_appears_offline_summary" + android:key="SETTINGS_PRESENCE_USER_ALWAYS_APPEARS_OFFLINE" + android:defaultValue="@bool/settings_presence_user_always_appears_offline_default" /> + + </im.vector.app.core.preference.VectorPreferenceCategory> + <im.vector.app.core.preference.VectorPreferenceCategory android:title="@string/settings_category_room_directory"> <im.vector.app.core.preference.VectorSwitchPreference diff --git a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt index a682d025b8..62fc9548b2 100644 --- a/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt +++ b/vector/src/test/java/im/vector/app/features/onboarding/OnboardingViewModelTest.kt @@ -18,8 +18,10 @@ package im.vector.app.features.onboarding import android.net.Uri import com.airbnb.mvrx.test.MvRxTestRule +import im.vector.app.features.login.LoginMode import im.vector.app.features.login.ReAuthHelper import im.vector.app.features.login.SignMode +import im.vector.app.features.onboarding.StartAuthenticationFlowUseCase.StartAuthenticationResult import im.vector.app.test.fakes.FakeActiveSessionHolder import im.vector.app.test.fakes.FakeAnalyticsTracker import im.vector.app.test.fakes.FakeAuthenticationService @@ -30,6 +32,7 @@ import im.vector.app.test.fakes.FakeHomeServerHistoryService import im.vector.app.test.fakes.FakeRegisterActionHandler import im.vector.app.test.fakes.FakeRegistrationWizard import im.vector.app.test.fakes.FakeSession +import im.vector.app.test.fakes.FakeStartAuthenticationFlowUseCase import im.vector.app.test.fakes.FakeStringProvider import im.vector.app.test.fakes.FakeUri import im.vector.app.test.fakes.FakeUriFilenameResolver @@ -41,6 +44,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Before import org.junit.Rule import org.junit.Test +import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig import org.matrix.android.sdk.api.auth.registration.FlowResult import org.matrix.android.sdk.api.auth.registration.RegisterThreePid import org.matrix.android.sdk.api.auth.registration.RegistrationResult @@ -58,6 +62,9 @@ private val A_HOMESERVER_CAPABILITIES = aHomeServerCapabilities(canChangeDisplay private val AN_IGNORED_FLOW_RESULT = FlowResult(missingStages = emptyList(), completedStages = emptyList()) private val ANY_CONTINUING_REGISTRATION_RESULT = RegistrationResult.FlowResponse(AN_IGNORED_FLOW_RESULT) private val A_LOGIN_OR_REGISTER_ACTION = OnboardingAction.LoginOrRegister("@a-user:id.org", "a-password", "a-device-name") +private const val A_HOMESERVER_URL = "https://edited-homeserver.org" +private val A_HOMESERVER_CONFIG = HomeServerConnectionConfig(FakeUri().instance) +private val SELECTED_HOMESERVER_STATE = SelectedHomeserverState(preferredLoginMode = LoginMode.Password) class OnboardingViewModelTest { @@ -66,7 +73,6 @@ class OnboardingViewModelTest { private val fakeUri = FakeUri() private val fakeContext = FakeContext() - private val initialState = OnboardingViewState() private val fakeSession = FakeSession() private val fakeUriFilenameResolver = FakeUriFilenameResolver() private val fakeActiveSessionHolder = FakeActiveSessionHolder(fakeSession) @@ -74,12 +80,16 @@ class OnboardingViewModelTest { private val fakeRegisterActionHandler = FakeRegisterActionHandler() private val fakeDirectLoginUseCase = FakeDirectLoginUseCase() private val fakeVectorFeatures = FakeVectorFeatures() + private val fakeHomeServerConnectionConfigFactory = FakeHomeServerConnectionConfigFactory() + private val fakeStartAuthenticationFlowUseCase = FakeStartAuthenticationFlowUseCase() + private val fakeHomeServerHistoryService = FakeHomeServerHistoryService() - lateinit var viewModel: OnboardingViewModel + private var initialState = OnboardingViewState() + private lateinit var viewModel: OnboardingViewModel @Before fun setUp() { - viewModel = createViewModel() + viewModelWith(initialState) } @Test @@ -95,8 +105,7 @@ class OnboardingViewModelTest { @Test fun `given supports changing display name, when handling PersonalizeProfile, then emits contents choose display name`() = runTest { - val initialState = initialState.copy(personalizationState = PersonalizationState(supportsChangingDisplayName = true, supportsChangingProfilePicture = false)) - viewModel = createViewModel(initialState) + viewModelWith(initialState.copy(personalizationState = PersonalizationState(supportsChangingDisplayName = true, supportsChangingProfilePicture = false))) val test = viewModel.test() viewModel.handle(OnboardingAction.PersonalizeProfile) @@ -108,8 +117,7 @@ class OnboardingViewModelTest { @Test fun `given only supports changing profile picture, when handling PersonalizeProfile, then emits contents choose profile picture`() = runTest { - val initialState = initialState.copy(personalizationState = PersonalizationState(supportsChangingDisplayName = false, supportsChangingProfilePicture = true)) - viewModel = createViewModel(initialState) + viewModelWith(initialState.copy(personalizationState = PersonalizationState(supportsChangingDisplayName = false, supportsChangingProfilePicture = true))) val test = viewModel.test() viewModel.handle(OnboardingAction.PersonalizeProfile) @@ -121,8 +129,7 @@ class OnboardingViewModelTest { @Test fun `given has sign in with matrix id sign mode, when handling login or register action, then logs in directly`() = runTest { - val initialState = initialState.copy(signMode = SignMode.SignInWithMatrixId) - viewModel = createViewModel(initialState) + viewModelWith(initialState.copy(signMode = SignMode.SignInWithMatrixId)) fakeDirectLoginUseCase.givenSuccessResult(A_LOGIN_OR_REGISTER_ACTION, config = null, result = fakeSession) givenInitialisesSession(fakeSession) val test = viewModel.test() @@ -141,8 +148,7 @@ class OnboardingViewModelTest { @Test fun `given has sign in with matrix id sign mode, when handling login or register action fails, then emits error`() = runTest { - val initialState = initialState.copy(signMode = SignMode.SignInWithMatrixId) - viewModel = createViewModel(initialState) + viewModelWith(initialState.copy(signMode = SignMode.SignInWithMatrixId)) fakeDirectLoginUseCase.givenFailureResult(A_LOGIN_OR_REGISTER_ACTION, config = null, cause = AN_ERROR) givenInitialisesSession(fakeSession) val test = viewModel.test() @@ -224,6 +230,50 @@ class OnboardingViewModelTest { .finish() } + @Test + fun `given in the sign up flow, when editing homeserver, then updates selected homeserver state and emits edited event`() = runTest { + viewModelWith(initialState.copy(onboardingFlow = OnboardingFlow.SignUp)) + fakeHomeServerConnectionConfigFactory.givenConfigFor(A_HOMESERVER_URL, A_HOMESERVER_CONFIG) + fakeStartAuthenticationFlowUseCase.givenResult(A_HOMESERVER_CONFIG, StartAuthenticationResult(isHomeserverOutdated = false, SELECTED_HOMESERVER_STATE)) + givenRegistrationResultFor(RegisterAction.StartRegistration, RegistrationResult.FlowResponse(AN_IGNORED_FLOW_RESULT)) + fakeHomeServerHistoryService.expectUrlToBeAdded(A_HOMESERVER_CONFIG.homeServerUri.toString()) + val test = viewModel.test() + + viewModel.handle(OnboardingAction.HomeServerChange.EditHomeServer(A_HOMESERVER_URL)) + + test + .assertStatesChanges( + initialState, + { copy(isLoading = true) }, + { copy(selectedHomeserver = SELECTED_HOMESERVER_STATE) }, + { copy(isLoading = false) } + + ) + .assertEvents(OnboardingViewEvents.OnHomeserverEdited) + .finish() + } + + @Test + fun `given in the sign up flow, when editing homeserver errors, then does not update the selected homeserver state and emits error`() = runTest { + viewModelWith(initialState.copy(onboardingFlow = OnboardingFlow.SignUp)) + fakeHomeServerConnectionConfigFactory.givenConfigFor(A_HOMESERVER_URL, A_HOMESERVER_CONFIG) + fakeStartAuthenticationFlowUseCase.givenResult(A_HOMESERVER_CONFIG, StartAuthenticationResult(isHomeserverOutdated = false, SELECTED_HOMESERVER_STATE)) + givenRegistrationActionErrors(RegisterAction.StartRegistration, AN_ERROR) + fakeHomeServerHistoryService.expectUrlToBeAdded(A_HOMESERVER_CONFIG.homeServerUri.toString()) + val test = viewModel.test() + + viewModel.handle(OnboardingAction.HomeServerChange.EditHomeServer(A_HOMESERVER_URL)) + + test + .assertStatesChanges( + initialState, + { copy(isLoading = true) }, + { copy(isLoading = false) } + ) + .assertEvents(OnboardingViewEvents.Failure(AN_ERROR)) + .finish() + } + @Test fun `given personalisation enabled, when registering account, then updates state and emits account created event`() = runTest { fakeVectorFeatures.givenPersonalisationEnabled() @@ -263,14 +313,13 @@ class OnboardingViewModelTest { @Test fun `given changing profile picture is supported, when updating display name, then updates upstream user display name and moves to choose profile picture`() = runTest { - val personalisedInitialState = initialState.copy(personalizationState = PersonalizationState(supportsChangingProfilePicture = true)) - viewModel = createViewModel(personalisedInitialState) + viewModelWith(initialState.copy(personalizationState = PersonalizationState(supportsChangingProfilePicture = true))) val test = viewModel.test() viewModel.handle(OnboardingAction.UpdateDisplayName(A_DISPLAY_NAME)) test - .assertStatesChanges(personalisedInitialState, expectedSuccessfulDisplayNameUpdateStates()) + .assertStatesChanges(initialState, expectedSuccessfulDisplayNameUpdateStates()) .assertEvents(OnboardingViewEvents.OnChooseProfilePicture) .finish() fakeSession.fakeProfileService.verifyUpdatedName(fakeSession.myUserId, A_DISPLAY_NAME) @@ -278,14 +327,13 @@ class OnboardingViewModelTest { @Test fun `given changing profile picture is not supported, when updating display name, then updates upstream user display name and completes personalization`() = runTest { - val personalisedInitialState = initialState.copy(personalizationState = PersonalizationState(supportsChangingProfilePicture = false)) - viewModel = createViewModel(personalisedInitialState) + viewModelWith(initialState.copy(personalizationState = PersonalizationState(supportsChangingProfilePicture = false))) val test = viewModel.test() viewModel.handle(OnboardingAction.UpdateDisplayName(A_DISPLAY_NAME)) test - .assertStatesChanges(personalisedInitialState, expectedSuccessfulDisplayNameUpdateStates()) + .assertStatesChanges(initialState, expectedSuccessfulDisplayNameUpdateStates()) .assertEvents(OnboardingViewEvents.OnPersonalizationComplete) .finish() fakeSession.fakeProfileService.verifyUpdatedName(fakeSession.myUserId, A_DISPLAY_NAME) @@ -325,14 +373,13 @@ class OnboardingViewModelTest { @Test fun `given a selected picture, when handling save selected profile picture, then updates upstream avatar and completes personalization`() = runTest { - val initialStateWithPicture = givenPictureSelected(fakeUri.instance, A_PICTURE_FILENAME) - viewModel = createViewModel(initialStateWithPicture) + viewModelWith(givenPictureSelected(fakeUri.instance, A_PICTURE_FILENAME)) val test = viewModel.test() viewModel.handle(OnboardingAction.SaveSelectedProfilePicture) test - .assertStates(expectedProfilePictureSuccessStates(initialStateWithPicture)) + .assertStates(expectedProfilePictureSuccessStates(initialState)) .assertEvents(OnboardingViewEvents.OnPersonalizationComplete) .finish() fakeSession.fakeProfileService.verifyAvatarUpdated(fakeSession.myUserId, fakeUri.instance, A_PICTURE_FILENAME) @@ -341,14 +388,13 @@ class OnboardingViewModelTest { @Test fun `given upstream update avatar fails, when saving selected profile picture, then emits failure event`() = runTest { fakeSession.fakeProfileService.givenUpdateAvatarErrors(AN_ERROR) - val initialStateWithPicture = givenPictureSelected(fakeUri.instance, A_PICTURE_FILENAME) - viewModel = createViewModel(initialStateWithPicture) + viewModelWith(givenPictureSelected(fakeUri.instance, A_PICTURE_FILENAME)) val test = viewModel.test() viewModel.handle(OnboardingAction.SaveSelectedProfilePicture) test - .assertStates(expectedProfilePictureFailureStates(initialStateWithPicture)) + .assertStates(expectedProfilePictureFailureStates(initialState)) .assertEvents(OnboardingViewEvents.Failure(AN_ERROR)) .finish() } @@ -377,23 +423,27 @@ class OnboardingViewModelTest { .finish() } - private fun createViewModel(state: OnboardingViewState = initialState): OnboardingViewModel { - return OnboardingViewModel( + private fun viewModelWith(state: OnboardingViewState) { + OnboardingViewModel( state, fakeContext.instance, fakeAuthenticationService, fakeActiveSessionHolder.instance, - FakeHomeServerConnectionConfigFactory().instance, + fakeHomeServerConnectionConfigFactory.instance, ReAuthHelper(), FakeStringProvider().instance, - FakeHomeServerHistoryService(), + fakeHomeServerHistoryService, fakeVectorFeatures, FakeAnalyticsTracker(), fakeUriFilenameResolver.instance, fakeRegisterActionHandler.instance, fakeDirectLoginUseCase.instance, + fakeStartAuthenticationFlowUseCase.instance, FakeVectorOverrides() - ) + ).also { + viewModel = it + initialState = state + } } private fun givenPictureSelected(fileUri: Uri, filename: String): OnboardingViewState { @@ -451,6 +501,12 @@ class OnboardingViewModelTest { fakeAuthenticationService.givenRegistrationWizard(registrationWizard) fakeRegisterActionHandler.givenResultsFor(registrationWizard, results) } + + private fun givenRegistrationActionErrors(action: RegisterAction, cause: Throwable) { + val registrationWizard = FakeRegistrationWizard() + fakeAuthenticationService.givenRegistrationWizard(registrationWizard) + fakeRegisterActionHandler.givenThrowsFor(registrationWizard, action, cause) + } } private fun HomeServerCapabilities.toPersonalisationState() = PersonalizationState( diff --git a/vector/src/test/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCaseTest.kt b/vector/src/test/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCaseTest.kt new file mode 100644 index 0000000000..b75ec231fd --- /dev/null +++ b/vector/src/test/java/im/vector/app/features/onboarding/StartAuthenticationFlowUseCaseTest.kt @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.features.onboarding + +import im.vector.app.R +import im.vector.app.features.login.LoginMode +import im.vector.app.features.onboarding.StartAuthenticationFlowUseCase.StartAuthenticationResult +import im.vector.app.test.fakes.FakeAuthenticationService +import im.vector.app.test.fakes.FakeStringProvider +import im.vector.app.test.fakes.FakeUri +import im.vector.app.test.fakes.toTestString +import io.mockk.coVerifyOrder +import kotlinx.coroutines.test.runTest +import org.amshove.kluent.shouldBeEqualTo +import org.junit.Before +import org.junit.Test +import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig +import org.matrix.android.sdk.api.auth.data.LoginFlowResult +import org.matrix.android.sdk.api.auth.data.LoginFlowTypes +import org.matrix.android.sdk.api.auth.data.SsoIdentityProvider + +private const val MATRIX_ORG_URL = "https://any-value.org/" +private const val A_DECLARED_HOMESERVER_URL = "https://foo.bar" +private val A_HOMESERVER_CONFIG = HomeServerConnectionConfig(homeServerUri = FakeUri().instance) +private val SSO_IDENTITY_PROVIDERS = emptyList<SsoIdentityProvider>() + +class StartAuthenticationFlowUseCaseTest { + + private val fakeAuthenticationService = FakeAuthenticationService() + private val fakeStringProvider = FakeStringProvider() + + private val useCase = StartAuthenticationFlowUseCase(fakeAuthenticationService, fakeStringProvider.instance) + + @Before + fun setUp() { + fakeAuthenticationService.expectedCancelsPendingLogin() + } + + @Test + fun `given empty login result when starting authentication flow then returns empty result`() = runTest { + val loginResult = aLoginResult() + fakeAuthenticationService.givenLoginFlow(A_HOMESERVER_CONFIG, loginResult) + + val result = useCase.execute(A_HOMESERVER_CONFIG) + + result shouldBeEqualTo expectedResult() + verifyClearsAndThenStartsLogin(A_HOMESERVER_CONFIG) + } + + @Test + fun `given login supports SSO and Password when starting authentication flow then prefers SsoAndPassword`() = runTest { + val supportedLoginTypes = listOf(LoginFlowTypes.SSO, LoginFlowTypes.PASSWORD) + val loginResult = aLoginResult(supportedLoginTypes = supportedLoginTypes) + fakeAuthenticationService.givenLoginFlow(A_HOMESERVER_CONFIG, loginResult) + + val result = useCase.execute(A_HOMESERVER_CONFIG) + + result shouldBeEqualTo expectedResult( + supportedLoginTypes = supportedLoginTypes, + preferredLoginMode = LoginMode.SsoAndPassword(SSO_IDENTITY_PROVIDERS), + ) + verifyClearsAndThenStartsLogin(A_HOMESERVER_CONFIG) + } + + @Test + fun `given login supports SSO when starting authentication flow then prefers Sso`() = runTest { + val supportedLoginTypes = listOf(LoginFlowTypes.SSO) + val loginResult = aLoginResult(supportedLoginTypes = supportedLoginTypes) + fakeAuthenticationService.givenLoginFlow(A_HOMESERVER_CONFIG, loginResult) + + val result = useCase.execute(A_HOMESERVER_CONFIG) + + result shouldBeEqualTo expectedResult( + supportedLoginTypes = supportedLoginTypes, + preferredLoginMode = LoginMode.Sso(SSO_IDENTITY_PROVIDERS), + ) + verifyClearsAndThenStartsLogin(A_HOMESERVER_CONFIG) + } + + @Test + fun `given login supports Password when starting authentication flow then prefers Password`() = runTest { + val supportedLoginTypes = listOf(LoginFlowTypes.PASSWORD) + val loginResult = aLoginResult(supportedLoginTypes = supportedLoginTypes) + fakeAuthenticationService.givenLoginFlow(A_HOMESERVER_CONFIG, loginResult) + + val result = useCase.execute(A_HOMESERVER_CONFIG) + + result shouldBeEqualTo expectedResult( + supportedLoginTypes = supportedLoginTypes, + preferredLoginMode = LoginMode.Password, + ) + verifyClearsAndThenStartsLogin(A_HOMESERVER_CONFIG) + } + + @Test + fun `given matrix dot org url when starting authentication flow then provides description`() = runTest { + val matrixOrgConfig = HomeServerConnectionConfig(homeServerUri = FakeUri(MATRIX_ORG_URL).instance) + fakeStringProvider.given(R.string.matrix_org_server_url, result = MATRIX_ORG_URL) + fakeAuthenticationService.givenLoginFlow(matrixOrgConfig, aLoginResult()) + + val result = useCase.execute(matrixOrgConfig) + + result shouldBeEqualTo expectedResult( + description = R.string.ftue_auth_create_account_matrix_dot_org_server_description.toTestString(), + homeserverSourceUrl = MATRIX_ORG_URL + ) + verifyClearsAndThenStartsLogin(matrixOrgConfig) + } + + private fun aLoginResult( + supportedLoginTypes: List<String> = emptyList() + ) = LoginFlowResult( + supportedLoginTypes = supportedLoginTypes, + ssoIdentityProviders = SSO_IDENTITY_PROVIDERS, + isLoginAndRegistrationSupported = true, + homeServerUrl = A_DECLARED_HOMESERVER_URL, + isOutdatedHomeserver = false + ) + + private fun expectedResult( + isHomeserverOutdated: Boolean = false, + description: String? = null, + preferredLoginMode: LoginMode = LoginMode.Unsupported, + supportedLoginTypes: List<String> = emptyList(), + homeserverSourceUrl: String = A_HOMESERVER_CONFIG.homeServerUri.toString() + ) = StartAuthenticationResult( + isHomeserverOutdated, + SelectedHomeserverState( + description = description, + userFacingUrl = homeserverSourceUrl, + upstreamUrl = A_DECLARED_HOMESERVER_URL, + preferredLoginMode = preferredLoginMode, + supportedLoginTypes = supportedLoginTypes + ) + ) + + private fun verifyClearsAndThenStartsLogin(homeServerConnectionConfig: HomeServerConnectionConfig) { + coVerifyOrder { + fakeAuthenticationService.cancelPendingLoginOrRegistration() + fakeAuthenticationService.getLoginFlow(homeServerConnectionConfig) + } + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt index 9175fd3750..fedda18aeb 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeAuthenticationService.kt @@ -22,6 +22,7 @@ import io.mockk.every import io.mockk.mockk import org.matrix.android.sdk.api.auth.AuthenticationService import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig +import org.matrix.android.sdk.api.auth.data.LoginFlowResult import org.matrix.android.sdk.api.auth.registration.RegistrationWizard import org.matrix.android.sdk.api.auth.wellknown.WellknownResult @@ -35,10 +36,18 @@ class FakeAuthenticationService : AuthenticationService by mockk() { every { isRegistrationStarted } returns started } + fun givenLoginFlow(config: HomeServerConnectionConfig, result: LoginFlowResult) { + coEvery { getLoginFlow(config) } returns result + } + fun expectReset() { coJustRun { reset() } } + fun expectedCancelsPendingLogin() { + coJustRun { cancelPendingLoginOrRegistration() } + } + fun givenWellKnown(matrixId: String, config: HomeServerConnectionConfig?, result: WellknownResult) { coEvery { getWellKnownData(matrixId, config) } returns result } @@ -52,6 +61,6 @@ class FakeAuthenticationService : AuthenticationService by mockk() { } fun givenDirectAuthenticationThrows(config: HomeServerConnectionConfig, matrixId: String, password: String, deviceName: String, cause: Throwable) { - coEvery { directAuthentication(config, matrixId, password, deviceName) } throws cause + coEvery { directAuthentication(config, matrixId, password, deviceName) } throws cause } } diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt index 1ec1f31b45..ed571fc2f2 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeCryptoService.kt @@ -19,7 +19,7 @@ package im.vector.app.test.fakes import androidx.lifecycle.MutableLiveData import io.mockk.mockk import org.matrix.android.sdk.api.session.crypto.CryptoService -import org.matrix.android.sdk.internal.crypto.model.CryptoDeviceInfo +import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo class FakeCryptoService : CryptoService by mockk() { diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeHomeServerConnectionConfigFactory.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeHomeServerConnectionConfigFactory.kt index a0e60e5a18..553a35ad8c 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeHomeServerConnectionConfigFactory.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeHomeServerConnectionConfigFactory.kt @@ -17,9 +17,14 @@ package im.vector.app.test.fakes import im.vector.app.features.login.HomeServerConnectionConfigFactory +import io.mockk.every import io.mockk.mockk +import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig class FakeHomeServerConnectionConfigFactory { - val instance: HomeServerConnectionConfigFactory = mockk() + + fun givenConfigFor(url: String, config: HomeServerConnectionConfig) { + every { instance.create(url) } returns config + } } diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeHomeServerHistoryService.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeHomeServerHistoryService.kt index 6cdcb02156..4d9960991f 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeHomeServerHistoryService.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeHomeServerHistoryService.kt @@ -16,9 +16,13 @@ package im.vector.app.test.fakes +import io.mockk.justRun import io.mockk.mockk import org.matrix.android.sdk.api.auth.HomeServerHistoryService class FakeHomeServerHistoryService : HomeServerHistoryService by mockk() { override fun getKnownServersUrls() = emptyList<String>() + fun expectUrlToBeAdded(url: String) { + justRun { addHomeServerToHistory(url) } + } } diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeRegisterActionHandler.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeRegisterActionHandler.kt index 8d595d91e9..61d0e438ab 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeRegisterActionHandler.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeRegisterActionHandler.kt @@ -33,4 +33,8 @@ class FakeRegisterActionHandler { result.first { it.first == actionArg }.second } } + + fun givenThrowsFor(wizard: RegistrationWizard, action: RegisterAction, cause: Throwable) { + coEvery { instance.handleRegisterAction(wizard, action) } throws cause + } } diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeStartAuthenticationFlowUseCase.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeStartAuthenticationFlowUseCase.kt new file mode 100644 index 0000000000..697de6bf25 --- /dev/null +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeStartAuthenticationFlowUseCase.kt @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 New Vector Ltd + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package im.vector.app.test.fakes + +import im.vector.app.features.onboarding.StartAuthenticationFlowUseCase +import im.vector.app.features.onboarding.StartAuthenticationFlowUseCase.StartAuthenticationResult +import io.mockk.coEvery +import io.mockk.mockk +import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig + +class FakeStartAuthenticationFlowUseCase { + + val instance = mockk<StartAuthenticationFlowUseCase>() + + fun givenResult(config: HomeServerConnectionConfig, result: StartAuthenticationResult) { + coEvery { instance.execute(config) } returns result + } +} diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeStringProvider.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeStringProvider.kt index 1a4f5cb85b..e63550abe0 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeStringProvider.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeStringProvider.kt @@ -21,7 +21,6 @@ import io.mockk.every import io.mockk.mockk class FakeStringProvider { - val instance = mockk<StringProvider>() init { @@ -29,6 +28,10 @@ class FakeStringProvider { "test-${args[0]}" } } + + fun given(id: Int, result: String) { + every { instance.getString(id) } returns result + } } fun Int.toTestString() = "test-$this" diff --git a/vector/src/test/java/im/vector/app/test/fakes/FakeUri.kt b/vector/src/test/java/im/vector/app/test/fakes/FakeUri.kt index 675401d72f..08bfac8db1 100644 --- a/vector/src/test/java/im/vector/app/test/fakes/FakeUri.kt +++ b/vector/src/test/java/im/vector/app/test/fakes/FakeUri.kt @@ -25,7 +25,10 @@ class FakeUri(contentEquals: String? = null) { val instance = mockk<Uri>() init { - contentEquals?.let { givenEquals(it) } + contentEquals?.let { + givenEquals(it) + every { instance.toString() } returns it + } } fun givenNonHierarchical() {