mirror of
https://github.com/vector-im/riotX-android
synced 2025-10-06 08:12:46 +02:00
Compare commits
18 Commits
tech/fix-v
...
feature/sq
Author | SHA1 | Date | |
---|---|---|---|
|
9903a299b9 | ||
|
9a4cad1e45 | ||
|
649b4496a6 | ||
|
617b76c0d5 | ||
|
9415d9b5c5 | ||
|
3ba5e97392 | ||
|
0ef5ae38d0 | ||
|
c53f9359d7 | ||
|
09c98c32f0 | ||
|
fc90844556 | ||
|
0ca7e6202c | ||
|
96162218e4 | ||
|
ffaacdf436 | ||
|
39fdda3715 | ||
|
af171b3b7e | ||
|
3dd9693f59 | ||
|
8b0845a76b | ||
|
8e896600c9 |
928
.editorconfig
928
.editorconfig
@@ -1,901 +1,33 @@
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
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
|
||||
# For ktlint configuration. Ref: https://ktlint.github.io/
|
||||
|
||||
[*.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
|
||||
[*.{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
|
||||
|
||||
[*.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
|
||||
# Comma-separated list of rules to disable (Since 0.34.0)
|
||||
# Note that rules in any ruleset other than the standard ruleset will need to be prefixed
|
||||
# by the ruleset identifier.
|
||||
disabled_rules=no-multi-spaces,colon-spacing,chain-wrapping,import-ordering,experimental:annotation
|
||||
|
||||
[.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 = false
|
||||
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 = true
|
||||
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 = true
|
||||
ij_kotlin_method_parameters_right_paren_on_new_line = true
|
||||
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
|
||||
# The following (so far identified) rules are kept:
|
||||
# no-blank-line-before-rbrace
|
||||
# final-newline
|
||||
# no-consecutive-blank-lines
|
||||
# comment-spacing
|
||||
# filename
|
||||
# comma-spacing
|
||||
# paren-spacing
|
||||
# op-spacing
|
||||
# string-template
|
||||
# no-unused-imports
|
||||
# curly-spacing
|
||||
# no-semi
|
||||
# no-empty-class-body
|
||||
# experimental:multiline-if-else
|
||||
# experimental:no-empty-first-line-in-method-block
|
||||
# no-wildcard-imports
|
||||
|
86
.github/ISSUE_TEMPLATE/bug.yml
vendored
86
.github/ISSUE_TEMPLATE/bug.yml
vendored
@@ -1,86 +0,0 @@
|
||||
name: Bug report for the Element Android app
|
||||
description: Report any issues that you have found with the Element app. Please [check open issues](https://github.com/vector-im/element-android/issues) first, in case it has already been reported.
|
||||
labels: [T-Defect]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this bug report!
|
||||
|
||||
Please report security issues by email to security@matrix.org
|
||||
- type: textarea
|
||||
id: reproduction-steps
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Please attach screenshots, videos or logs if you can.
|
||||
placeholder: Tell us what you see!
|
||||
value: |
|
||||
1. Where are you starting? What can you see?
|
||||
2. What do you click?
|
||||
3. More steps…
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: result
|
||||
attributes:
|
||||
label: Outcome
|
||||
placeholder: Tell us what went wrong
|
||||
value: |
|
||||
#### What did you expect?
|
||||
|
||||
#### What happened instead?
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: device
|
||||
attributes:
|
||||
label: Your phone model
|
||||
placeholder: e.g. Samsung S6
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: os
|
||||
attributes:
|
||||
label: Operating system version
|
||||
placeholder: e.g. Android 10.0
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: Application version and app store
|
||||
description: You can find the version information in Settings -> Help & About.
|
||||
placeholder: e.g. Element version 1.7.34, olm version 3.2.3 from F-Droid
|
||||
validations:
|
||||
required: false
|
||||
- type: input
|
||||
id: homeserver
|
||||
attributes:
|
||||
label: Homeserver
|
||||
description: |
|
||||
Which server is your account registered on? If it is a local or non-public homeserver, please tell us what is the homeserver implementation (ex: Synapse/Dendrite/etc.) and the version.
|
||||
placeholder: e.g. matrix.org or Synapse 1.50.0rc1
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: rageshake
|
||||
attributes:
|
||||
label: Will you send logs?
|
||||
description: |
|
||||
Did you know that you can shake your phone to submit logs for this issue? Trigger the defect, then shake your phone and you will see a popup asking if you would like to open the bug report screen. Click YES, and describe the issue, mentioning that you have also filed a bug (it's helpful if you can include a link to the bug). Send the report to submit anonymous logs to the developers.
|
||||
options:
|
||||
- 'Yes'
|
||||
- 'No'
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
id: pr
|
||||
attributes:
|
||||
label: Are you willing to provide a PR?
|
||||
description: |
|
||||
Providing a PR can drastically speed up the process of fixing this bug. Don't worry, it's still OK to answer 'No' :).
|
||||
options:
|
||||
- 'Yes'
|
||||
- 'No'
|
||||
validations:
|
||||
required: true
|
47
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
47
.github/ISSUE_TEMPLATE/enhancement.yml
vendored
@@ -1,47 +0,0 @@
|
||||
name: Enhancement request
|
||||
description: Do you have a suggestion or feature request?
|
||||
labels: [T-Enhancement]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for taking the time to propose a new feature or make a suggestion.
|
||||
- type: textarea
|
||||
id: usecase
|
||||
attributes:
|
||||
label: Your use case
|
||||
description: Please feel welcome to include screenshots or mock ups.
|
||||
placeholder: Tell us what you would like to do!
|
||||
value: |
|
||||
#### What would you like to do?
|
||||
|
||||
#### Why would you like to do it?
|
||||
|
||||
#### How would you like to achieve it?
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: alternative
|
||||
attributes:
|
||||
label: Have you considered any alternatives?
|
||||
placeholder: A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: false
|
||||
- type: textarea
|
||||
id: additional-context
|
||||
attributes:
|
||||
label: Additional context
|
||||
placeholder: Is there anything else you'd like to add?
|
||||
validations:
|
||||
required: false
|
||||
- type: dropdown
|
||||
id: pr
|
||||
attributes:
|
||||
label: Are you willing to provide a PR?
|
||||
description: |
|
||||
Don't worry, it's still OK to answer 'No' :).
|
||||
options:
|
||||
- 'Yes'
|
||||
- 'No'
|
||||
validations:
|
||||
required: true
|
20
.github/ISSUE_TEMPLATE/matrix-sdk.yml
vendored
20
.github/ISSUE_TEMPLATE/matrix-sdk.yml
vendored
@@ -1,20 +0,0 @@
|
||||
name: Matrix SDK bug or enhancement
|
||||
description: Report issue or ask for a feature in the [Android Matrix SDK](https://github.com/matrix-org/matrix-android-sdk2)
|
||||
title: "[SDK] "
|
||||
labels: [matrix-sdk]
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thanks for taking the time to fill out this issue!
|
||||
|
||||
Please report security issues by email to security@matrix.org
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: Report issue or ask for a feature in the [Android Matrix SDK](https://github.com/matrix-org/matrix-android-sdk2)
|
||||
placeholder: This issue template should be used by third party application maintainers, to report a bug or to request a feature on the SDK module of the Element Android application.
|
||||
validations:
|
||||
required: true
|
134
.github/ISSUE_TEMPLATE/release.yml
vendored
134
.github/ISSUE_TEMPLATE/release.yml
vendored
@@ -1,134 +0,0 @@
|
||||
name: Release checklist
|
||||
description: Checklist for each release. This template is only for the core team.
|
||||
title: "[Release] Element Android v"
|
||||
labels: [🚀 Release]
|
||||
assignees:
|
||||
- bmarty
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
id: checklist
|
||||
attributes:
|
||||
label: Release checklist
|
||||
description: For the template example, we are releasing the version 1.2.3. Replace 1.2.3 with the version in the issue body.
|
||||
placeholder: |
|
||||
If you are reading this, you have deleted the content of the release template: undo the deletion or start again.
|
||||
value: |
|
||||
### Before the release
|
||||
|
||||
- [ ] 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.
|
||||
|
||||
- [ ] Ensure all [the required PRs](https://github.com/vector-im/element-android/pulls?q=is%3Aopen+is%3Apr+label%3AZ-NextRelease) have been merged
|
||||
|
||||
### Do the release
|
||||
|
||||
- [ ] Make sure `develop` and `main` are up to date (git pull)
|
||||
- [ ] Checkout develop and create a release with gitflow, branch name `release/1.2.3`
|
||||
- [ ] Check the crashes from the PlayStore
|
||||
- [ ] Check the rageshake with the current dev version: https://github.com/matrix-org/element-android-rageshakes/labels/1.2.3-dev
|
||||
- [ ] Run the integration test, and especially `UiAllScreensSanityTest.allScreensTest()`
|
||||
- [ ] Create an account on matrix.org and do some smoke tests that the sanity test does not cover like: 1-1 call, 1-1 video call, Jitsi call for instance
|
||||
- [ ] Run towncrier: `towncrier build --version v1.2.3 --draft` (remove `--draft` do write the file CHANGES.md)
|
||||
- [ ] Check that the folder `changelog.d` is empty. It can happen that some remaining files stay here
|
||||
- [ ] Check the file CHANGES.md consistency. It's possible to reorder items (most important changes first) or change their section if relevant. Also an opportunity to fix some typo, or rewrite things
|
||||
- [ ] Add file for fastlane under ./fastlane/metadata/android/en-US/changelogs
|
||||
- [ ] (optional) Push the branch and start a draft PR (will not be merged), to check that the CI is happy with all the changes.
|
||||
- [ ] Finish release with gitflow, delete the draft PR (if created)
|
||||
- [ ] Push `main` and the new tag `v1.2.3` to origin
|
||||
- [ ] Checkout `develop`
|
||||
- [ ] Increase version (versionPatch + 2) in `./vector/build.gradle`
|
||||
- [ ] Change the value of SDK_VERSION in the file `./matrix-sdk-android/build.gradle`
|
||||
- [ ] Commit and push `develop`
|
||||
- [ ] Wait for [Buildkite](https://buildkite.com/matrix-dot-org/element-android/builds?branch=main) to build the `main` branch.
|
||||
- [ ] Run the script `~/scripts/releaseElement.sh`. It will download the APKs from Buildkite check them and sign them.
|
||||
- [ ] Install the APK on your phone to check that the upgrade went well (no init sync, etc.)
|
||||
- [ ] Create the release on gitHub [from the tag](https://github.com/vector-im/element-android/tags), copy paste the block from the file CHANGES.md
|
||||
- [ ] Add the 4 signed APKs to the GitHub release
|
||||
- [ ] Ping the Android Internal room
|
||||
|
||||
### Once tested and validated internally
|
||||
|
||||
- [ ] Create a new open testing release on the GooglePlay console and upload the 4 signed Apks.
|
||||
- [ ] Check that the version codes are correct
|
||||
- [ ] Copy the fastlane change to the GooglePlay console in the section en-GB.
|
||||
- [ ] Push the open testing release to 100% of the users
|
||||
- [ ] Notify the F-Droid team [here](https://matrix.to/#/!LAAuJLQXYHjMNWKrCK:matrix.org?via=matrix.org&via=bubu1.eu&via=lant.uk) so that they can schedule the publication on F-Droid
|
||||
- [ ] The application is available to the PlayStore testers (live). Google can take between 1 hour and up to 7 days to approve the release.
|
||||
- [ ] The application is available to the F-Droid users.
|
||||
|
||||
### Once open testing is live on PlayStore
|
||||
|
||||
- [ ] Ping the Android public room and update its topic
|
||||
|
||||
### Once Live on F-Droid
|
||||
|
||||
- [ ] Update the Android public room topic
|
||||
|
||||
### After at least 2 days (generally next Monday)
|
||||
|
||||
- [ ] Check the [rageshakes](https://github.com/matrix-org/element-android-rageshakes/issues)
|
||||
- [ ] Check the crash reports on the GooglePlay console
|
||||
- [ ] Check the Android Element room for any reported issues on the new version
|
||||
- [ ] If all is OK, promote the open testing release to production. Generally using a 100% roll out, but can be a smaller value depending on the release content.
|
||||
- [ ] The application is available to the PlayStore users (live). Google can take (again!) between 1 hour and up to 7 days to approve the release.
|
||||
|
||||
### Once production is live on PlayStore
|
||||
|
||||
- [ ] Ping the Android public room and update its topic
|
||||
- [ ] Add an entry in the internal diary
|
||||
|
||||
### Android SDK2
|
||||
|
||||
The SDK2 and the sample app are released only when Element has been pushed to production.
|
||||
|
||||
- [ ] Checkout the `main` branch on Element Android project
|
||||
|
||||
#### On the SDK2 project
|
||||
|
||||
https://github.com/matrix-org/matrix-android-sdk2
|
||||
|
||||
- [ ] Create a release with GitFlow
|
||||
- [ ] Update the value of VERSION_NAME in the file gradle.properties
|
||||
- [ ] Update the files `./build.gradle` and `./gradle/gradle-wrapper.properties` manually, to use the latest version for the dependency. You can get inspired by the same files on Element Android project.
|
||||
- [ ] Run the script `./tools/import_from_element.sh`
|
||||
- [ ] Check the diff in the file `./matrix-sdk-android/build.gradle` and restore what may have been erased (in particular the line `apply plugin: "com.vanniktech.maven.publish"` and the line about the version)
|
||||
- [ ] Let the script finish to build the library
|
||||
- [ ] Update the file `CHANGES.md`
|
||||
- [ ] Finish the release using GitFlow
|
||||
- [ ] Push the branch `main`, the new tag and the branch `develop` to origin
|
||||
|
||||
##### Release on MavenCentral
|
||||
|
||||
- [ ] Checkout the branch `main`
|
||||
- [ ] Run the command `./gradlew publish --no-daemon --no-parallel`. You'll need some non-public element to do so
|
||||
- [ ] Run the command `./gradlew closeAndReleaseRepository`. If it is working well, you can jump directly to the final step of this section.
|
||||
|
||||
If `./gradlew closeAndReleaseRepository` fails (for instance, several repositories are waiting to be handled), you have to close and release the repository manually. Do the following steps:
|
||||
|
||||
- [ ] Connect to https://s01.oss.sonatype.org
|
||||
- [ ] Click on Staging Repositories and check the the files have been uploaded
|
||||
- [ ] Click on close
|
||||
- [ ] Wait (check Activity tab until step "Repository closed" is displayed)
|
||||
- [ ] Click on release. The staging repository will disappear
|
||||
|
||||
Final step
|
||||
|
||||
- [ ] Check that the release is available in https://repo1.maven.org/maven2/org/matrix/android/matrix-android-sdk2/ (it can take a few minutes)
|
||||
|
||||
##### Release on GitHub
|
||||
|
||||
- [ ] Create the release on GitHub from [the tag](https://github.com/matrix-org/matrix-android-sdk2/tags)
|
||||
- [ ] Upload the AAR on the GitHub release
|
||||
|
||||
### Android SDK2 sample
|
||||
|
||||
https://github.com/matrix-org/matrix-android-sdk2-sample
|
||||
|
||||
- [ ] Update the dependency to the new version of the SDK2. It can take a few minutes for MavenCentral to make the library available. You can check status on https://repo1.maven.org/maven2/org/matrix/android/matrix-android-sdk2/
|
||||
- [ ] Build and run the sample, you may have to fix some API break
|
||||
- [ ] Commit and push directly on `main`
|
||||
validations:
|
||||
required: true
|
58
.github/PULL_REQUEST_TEMPLATE.md
vendored
58
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -1,58 +1,10 @@
|
||||
<!-- Please read [CONTRIBUTING.md](https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md) before submitting your pull request -->
|
||||
|
||||
## Type of change
|
||||
### Pull Request Checklist
|
||||
|
||||
- [ ] Feature
|
||||
- [ ] Bugfix
|
||||
- [ ] Technical
|
||||
- [ ] Other :
|
||||
<!-- Please read [CONTRIBUTING.md](https://github.com/vector-im/riotX-android/blob/develop/CONTRIBUTING.md) before submitting your pull request -->
|
||||
|
||||
## Content
|
||||
|
||||
<!-- Describe shortly what has been changed -->
|
||||
|
||||
## Motivation and context
|
||||
|
||||
<!-- Provide link to the corresponding issue if applicable or explain the context -->
|
||||
|
||||
## Screenshots / GIFs
|
||||
|
||||
<!-- 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
|
||||
|
||||
<!-- Explain how you tested your development -->
|
||||
|
||||
- Step 1
|
||||
- Step 2
|
||||
- Step ...
|
||||
|
||||
## Tested devices
|
||||
|
||||
- [ ] Physical
|
||||
- [ ] Emulator
|
||||
- OS version(s):
|
||||
|
||||
## Checklist
|
||||
|
||||
<!-- Depending on the Pull Request content, it can be acceptable if some of the following checkboxes stay unchecked. -->
|
||||
|
||||
- [ ] Changes has been tested on an Android device or Android emulator with API 21
|
||||
- [ ] Changes has been tested on an Android device or Android emulator with API 16
|
||||
- [ ] UI change has been tested on both light and dark themes
|
||||
- [ ] Accessibility has been taken into account. See https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md#accessibility
|
||||
- [ ] Pull request is based on the develop branch
|
||||
- [ ] Pull request includes a new file under ./changelog.d. See https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md#changelog
|
||||
- [ ] Pull request updates [CHANGES.md](https://github.com/vector-im/riotX-android/blob/develop/CHANGES.md)
|
||||
- [ ] Pull request includes screenshots or videos if containing UI changes
|
||||
- [ ] Pull request includes a [sign off](https://matrix-org.github.io/synapse/latest/development/contributing_guide.html#sign-off)
|
||||
- [ ] You've made a self review of your PR
|
||||
- [ ] If you have modified the screen flow, or added new screens to the application, you have updated the test [UiAllScreensSanityTest.allScreensTest()](https://github.com/vector-im/element-android/blob/main/vector/src/androidTest/java/im/vector/app/ui/UiAllScreensSanityTest.kt#L73)
|
||||
- [ ] Pull request includes a [sign off](https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.md#sign-off)
|
||||
|
26
.github/dependabot.yml
vendored
26
.github/dependabot.yml
vendored
@@ -1,26 +0,0 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
# Updates for Github Actions used in the repo
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
reviewers:
|
||||
- "vector-im/element-android-reviewers"
|
||||
ignore:
|
||||
- dependency-name: "*github-script*"
|
||||
# Updates for Gradle dependencies used in the app
|
||||
- package-ecosystem: gradle
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 200
|
||||
reviewers:
|
||||
- "vector-im/element-android-reviewers"
|
||||
ignore:
|
||||
- dependency-name: com.google.zxing:core
|
92
.github/workflows/build.yml
vendored
92
.github/workflows/build.yml
vendored
@@ -1,92 +0,0 @@
|
||||
name: APK Build
|
||||
|
||||
on:
|
||||
pull_request: { }
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
|
||||
# Enrich gradle.properties for CI/CD
|
||||
env:
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
|
||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
|
||||
|
||||
jobs:
|
||||
debug:
|
||||
name: Build debug APKs (${{ matrix.target }})
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref != 'refs/heads/main'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target: [ Gplay, Fdroid ]
|
||||
# Allow all jobs on develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/develop' && format('integration-tests-develop-{0}-{1}', matrix.target, github.sha) || format('build-debug-{0}-{1}', matrix.target, github.ref) }}
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Assemble ${{ matrix.target }} debug apk
|
||||
run: ./gradlew assemble${{ matrix.target }}Debug $CI_GRADLE_ARG_PROPERTIES
|
||||
- name: Upload ${{ matrix.target }} debug APKs
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: vector-${{ matrix.target }}-debug
|
||||
path: |
|
||||
vector-app/build/outputs/apk/*/debug/*.apk
|
||||
|
||||
release:
|
||||
name: Build unsigned GPlay APKs
|
||||
runs-on: ubuntu-latest
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/head/main' && format('build-release-apk-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('build-release-apk-develop-{0}', github.sha) || format('build-debug-{0}', github.ref) }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/head/main' }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Assemble GPlay unsigned apk
|
||||
run: ./gradlew clean assembleGplayRelease $CI_GRADLE_ARG_PROPERTIES
|
||||
- name: Upload Gplay unsigned APKs
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: vector-gplay-release-unsigned
|
||||
path: |
|
||||
vector-app/build/outputs/apk/*/release/*.apk
|
||||
|
||||
exodus:
|
||||
runs-on: ubuntu-latest
|
||||
needs: release
|
||||
steps:
|
||||
- name: Obtain apk from artifact
|
||||
id: download
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: vector-gplay-release-unsigned
|
||||
- name: Show apks in artifact
|
||||
run: ls -R ${{steps.download.outputs.download-path}}
|
||||
- name: Execute exodus-standalone
|
||||
uses: docker://exodusprivacy/exodus-standalone:latest
|
||||
with:
|
||||
args: /github/workspace/gplay/release/vector-gplay-universal-release-unsigned.apk -j -o /github/workspace/exodus.json
|
||||
- name: Upload exodus json report
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: exodus.json
|
||||
path: |
|
||||
exodus.json
|
||||
- name: Check for trackers
|
||||
run: "jq -e '.trackers == []' exodus.json > /dev/null || { echo '::error static analysis identified user tracking library' ; exit 1; }"
|
20
.github/workflows/danger.yml
vendored
20
.github/workflows/danger.yml
vendored
@@ -1,20 +0,0 @@
|
||||
name: Danger CI
|
||||
|
||||
on: [pull_request]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: Danger
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- run: |
|
||||
npm install --save-dev @babel/plugin-transform-flow-strip-types
|
||||
- name: Danger
|
||||
uses: danger/danger-js@11.1.2
|
||||
with:
|
||||
args: "--dangerfile tools/danger/dangerfile.js"
|
||||
env:
|
||||
DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
|
||||
# Fallback for forks
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
22
.github/workflows/docs.yml
vendored
22
.github/workflows/docs.yml
vendored
@@ -1,22 +0,0 @@
|
||||
name: Documentation
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ develop ]
|
||||
|
||||
jobs:
|
||||
docs:
|
||||
name: Generate and publish Android Matrix SDK documentation
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Build docs
|
||||
run: ./gradlew dokkaHtml
|
||||
|
||||
- name: Deploy docs
|
||||
uses: peaceiris/actions-gh-pages@v3
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
publish_dir: ./matrix-sdk-android/build/dokka/html
|
14
.github/workflows/gradle-wrapper-validation.yml
vendored
14
.github/workflows/gradle-wrapper-validation.yml
vendored
@@ -1,14 +0,0 @@
|
||||
name: "Validate Gradle Wrapper"
|
||||
on:
|
||||
pull_request: { }
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
|
||||
jobs:
|
||||
validation:
|
||||
name: "Validation"
|
||||
runs-on: ubuntu-latest
|
||||
# No concurrency required, this is a prerequisite to other actions and should run every time.
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: gradle/wrapper-validation-action@v1
|
46
.github/workflows/nightly.yml
vendored
46
.github/workflows/nightly.yml
vendored
@@ -1,46 +0,0 @@
|
||||
name: Build and release nightly APK
|
||||
|
||||
on:
|
||||
schedule:
|
||||
# Every nights at 4
|
||||
- cron: "0 4 * * *"
|
||||
|
||||
env:
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
|
||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
|
||||
|
||||
jobs:
|
||||
nightly:
|
||||
name: Build and publish nightly Gplay APK to Firebase
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Install towncrier
|
||||
run: |
|
||||
python3 -m pip install towncrier
|
||||
- name: Prepare changelog file
|
||||
run: |
|
||||
mv towncrier.toml towncrier.toml.bak
|
||||
sed 's/CHANGES\.md/CHANGES_NIGHTLY\.md/' towncrier.toml.bak > towncrier.toml
|
||||
rm towncrier.toml.bak
|
||||
yes n | towncrier build --version nightly
|
||||
- name: Build and upload Gplay Nightly APK
|
||||
run: |
|
||||
./gradlew assembleGplayNightly appDistributionUploadGplayNightly $CI_GRADLE_ARG_PROPERTIES
|
||||
env:
|
||||
ELEMENT_ANDROID_NIGHTLY_KEYID: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYID }}
|
||||
ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_KEYPASSWORD }}
|
||||
ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_STOREPASSWORD }}
|
||||
FIREBASE_TOKEN: ${{ secrets.ELEMENT_ANDROID_NIGHTLY_FIREBASE_TOKEN }}
|
105
.github/workflows/post-pr.yml
vendored
105
.github/workflows/post-pr.yml
vendored
@@ -1,105 +0,0 @@
|
||||
name: Integration Tests
|
||||
|
||||
# This runs for all closed pull requests against main, including those closed without merge.
|
||||
# Further filtering occurs in 'should-i-run'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [closed]
|
||||
branches: [develop]
|
||||
|
||||
# Enrich gradle.properties for CI/CD
|
||||
env:
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
|
||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
|
||||
|
||||
jobs:
|
||||
|
||||
# More info on should-i-run:
|
||||
# If this fails to run (the IF doesn't complete) then the needs will not be satisfied for any of the
|
||||
# other jobs below, so none will run.
|
||||
# except for the notification job at the bottom which will run all the time, unless should-i-run isn't
|
||||
# successful, or all the other jobs have succeeded
|
||||
|
||||
should-i-run:
|
||||
name: Check if PR is suitable for analysis
|
||||
runs-on: ubuntu-latest
|
||||
if: github.event.pull_request.merged # Additionally require PR to have been completely merged.
|
||||
steps:
|
||||
- run: echo "Run those tests!" # no-op success
|
||||
|
||||
ui-tests:
|
||||
name: UI Tests (Synapse)
|
||||
needs: should-i-run
|
||||
runs-on: buildjet-4vcpu-ubuntu-2204
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
api-level: [ 28 ]
|
||||
# No concurrency required, runs every time on a schedule.
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- uses: actions/cache@v3
|
||||
with:
|
||||
path: |
|
||||
~/.gradle/caches
|
||||
~/.gradle/wrapper
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Start synapse server
|
||||
uses: michaelkaye/setup-matrix-synapse@v1.0.3
|
||||
with:
|
||||
uploadLogs: true
|
||||
httpPort: 8080
|
||||
disableRateLimiting: true
|
||||
public_baseurl: "http://10.0.2.2:8080/"
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
- name: Run sanity tests on API ${{ matrix.api-level }}
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
arch: x86
|
||||
profile: Nexus 5X
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
emulator-build: 7425822 # workaround to emulator bug: https://github.com/ReactiveCircus/android-emulator-runner/issues/160
|
||||
script: |
|
||||
adb root
|
||||
adb logcat -c
|
||||
touch emulator.log
|
||||
chmod 777 emulator.log
|
||||
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@v3
|
||||
if: always()
|
||||
with:
|
||||
name: uitest-error-results
|
||||
path: |
|
||||
emulator.log
|
||||
failure_screenshots/
|
||||
|
||||
# Notify the channel about delayed failures
|
||||
notify:
|
||||
name: Notify matrix
|
||||
runs-on: ubuntu-latest
|
||||
needs:
|
||||
- should-i-run
|
||||
- ui-tests
|
||||
if: always() && (needs.should-i-run.result == 'success' ) && ((needs.codecov-units.result != 'success' ) || (needs.ui-tests.result != 'success') || (needs.integration-tests.result != 'success'))
|
||||
# No concurrency required, runs every time on a schedule.
|
||||
steps:
|
||||
- uses: michaelkaye/matrix-hookshot-action@v1.0.0
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
hookshot_url: ${{ secrets.ELEMENT_ANDROID_HOOKSHOT_URL }}
|
||||
text_template: "Post-merge validation of ${{ github.head_ref }} into ${{ github.base_ref }} by ${{ github.event.pull_request.merged_by.login }} failed: {{#each job_statuses }}{{#with this }}{{#if completed }} {{name}} {{conclusion}} at {{completed_at}}, {{/if}}{{/with}}{{/each}}"
|
||||
html_template: "Post-merge validation of ${{ github.head_ref }} into ${{ github.base_ref }} by ${{ github.event.pull_request.merged_by.login }} failed: {{#each job_statuses }}{{#with this }}{{#if completed }}<br />{{icon conclusion}} {{name}} <font color='{{color conclusion}}'>{{conclusion}} at {{completed_at}} <a href=\"{{html_url}}\">[details]</a></font>{{/if}}{{/with}}{{/each}}"
|
94
.github/workflows/quality.yml
vendored
94
.github/workflows/quality.yml
vendored
@@ -1,94 +0,0 @@
|
||||
name: Code Quality Checks
|
||||
|
||||
on:
|
||||
pull_request: { }
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
|
||||
# Enrich gradle.properties for CI/CD
|
||||
env:
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -XX:MaxPermSize=512m -Dkotlin.daemon.jvm.options="-Xmx2g" -Dkotlin.incremental=false
|
||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
|
||||
|
||||
jobs:
|
||||
check:
|
||||
name: Project Check Suite
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run code quality check suite
|
||||
run: ./tools/check/check_code_quality.sh
|
||||
|
||||
# Knit for all the modules (https://github.com/Kotlin/kotlinx-knit)
|
||||
knit:
|
||||
name: Knit
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run knit
|
||||
run: |
|
||||
./gradlew knitCheck $CI_GRADLE_ARG_PROPERTIES
|
||||
|
||||
# Check the project: ktlint, detekt, lint
|
||||
lint:
|
||||
name: Android Linter
|
||||
runs-on: ubuntu-latest
|
||||
# Allow all jobs on main and develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/main' && format('lint-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('lint-develop-{0}', github.sha) || format('lint-{0}', github.ref) }}
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run ktlint
|
||||
run: |
|
||||
./gradlew ktlintCheck $CI_GRADLE_ARG_PROPERTIES --continue
|
||||
- name: Run detekt
|
||||
if: always()
|
||||
run: |
|
||||
./gradlew detekt $CI_GRADLE_ARG_PROPERTIES
|
||||
- name: Run lint
|
||||
# Not always, if ktlint or detekt fail, avoid running the long lint check.
|
||||
run: |
|
||||
./gradlew vector-app:lintGplayRelease $CI_GRADLE_ARG_PROPERTIES
|
||||
./gradlew vector-app:lintFdroidRelease $CI_GRADLE_ARG_PROPERTIES
|
||||
- name: Upload reports
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: linting-report
|
||||
path: |
|
||||
*/build/reports/**/*.*
|
||||
- name: Prepare Danger
|
||||
if: always()
|
||||
run: |
|
||||
npm install --save-dev @babel/core
|
||||
npm install --save-dev @babel/plugin-transform-flow-strip-types
|
||||
yarn add danger-plugin-lint-report --dev
|
||||
- name: Danger lint
|
||||
if: always()
|
||||
uses: danger/danger-js@11.1.2
|
||||
with:
|
||||
args: "--dangerfile tools/danger/dangerfile-lint.js"
|
||||
env:
|
||||
DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}
|
||||
# Fallback for forks
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
# Gradle dependency analysis using https://github.com/autonomousapps/dependency-analysis-android-gradle-plugin
|
||||
dependency-analysis:
|
||||
name: Dependency analysis
|
||||
runs-on: ubuntu-latest
|
||||
# Allow all jobs on main and develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/main' && format('dep-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('dep-develop-{0}', github.sha) || format('dep-{0}', github.ref) }}
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Dependency analysis
|
||||
run: ./gradlew dependencyCheckAnalyze $CI_GRADLE_ARG_PROPERTIES
|
||||
- name: Upload dependency analysis
|
||||
if: always()
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: dependency-analysis
|
||||
path: build/reports/dependency-check-report.html
|
83
.github/workflows/sync-from-external-sources.yml
vendored
83
.github/workflows/sync-from-external-sources.yml
vendored
@@ -1,83 +0,0 @@
|
||||
name: Sync Data From External Sources
|
||||
on:
|
||||
schedule:
|
||||
# At 00:00 on every Monday UTC
|
||||
- cron: '0 0 * * 1'
|
||||
|
||||
jobs:
|
||||
sync-emojis:
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: github.repository == 'vector-im/element-android'
|
||||
# No concurrency required, runs every time on a schedule.
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Install Prerequisite dependencies
|
||||
run: |
|
||||
pip install BeautifulSoup4
|
||||
pip install requests
|
||||
- name: Run Emoji script
|
||||
run: ./tools/import_emojis.py
|
||||
- name: Create Pull Request for Emojis
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: Sync Emojis
|
||||
title: Sync Emojis
|
||||
body: |
|
||||
- Update Emojis from Unicode.org
|
||||
branch: sync-emojis
|
||||
base: develop
|
||||
|
||||
sync-sas-strings:
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: github.repository == 'vector-im/element-android'
|
||||
# No concurrency required, runs every time on a schedule.
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.8
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- name: Install Prerequisite dependencies
|
||||
run: |
|
||||
pip install requests
|
||||
- name: Run SAS String script
|
||||
run: ./tools/import_sas_strings.py
|
||||
- name: Create Pull Request for SAS Strings
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: Sync SAS Strings
|
||||
title: Sync SAS Strings
|
||||
body: |
|
||||
- Update SAS Strings from matrix-doc.
|
||||
branch: sync-sas-strings
|
||||
base: develop
|
||||
|
||||
sync-analytics-plan:
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: github.repository == 'vector-im/element-android'
|
||||
# No concurrency required, runs every time on a schedule.
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run analytics import script
|
||||
run: ./tools/import_analytic_plan.sh
|
||||
- name: Create Pull Request for analytics plan
|
||||
uses: peter-evans/create-pull-request@v4
|
||||
with:
|
||||
commit-message: Sync analytics plan
|
||||
title: Sync analytics plan
|
||||
body: |
|
||||
### Update analytics plan
|
||||
Reviewers:
|
||||
- [ ] Please remove usage of Event or Enum which may have been removed or updated
|
||||
- [ ] please ensure new Events or new Enums are used to send analytics by pushing new commit(s) to this PR.
|
||||
|
||||
*Note*: Change are coming from [this project](https://github.com/matrix-org/matrix-analytics-events)
|
||||
branch: sync-analytics-plan
|
||||
base: develop
|
154
.github/workflows/tests.yml
vendored
154
.github/workflows/tests.yml
vendored
@@ -1,154 +0,0 @@
|
||||
name: Test
|
||||
|
||||
on:
|
||||
pull_request: { }
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
|
||||
# Enrich gradle.properties for CI/CD
|
||||
env:
|
||||
GRADLE_OPTS: -Dorg.gradle.jvmargs="-Xmx3072m -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError" -Dkotlin.daemon.jvm.options="-Xmx2560m" -Dkotlin.incremental=false
|
||||
CI_GRADLE_ARG_PROPERTIES: --stacktrace -PpreDexEnable=false --max-workers 2 --no-daemon
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: Runs all tests
|
||||
runs-on: buildjet-4vcpu-ubuntu-2204
|
||||
strategy:
|
||||
matrix:
|
||||
api-level: [28]
|
||||
# Allow all jobs on main and develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/main' && format('unit-tests-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('unit-tests-develop-{0}', github.sha) || format('unit-tests-{0}', github.ref) }}
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'adopt'
|
||||
java-version: '11'
|
||||
- uses: gradle/gradle-build-action@v2
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.8
|
||||
- uses: michaelkaye/setup-matrix-synapse@v1.0.3
|
||||
with:
|
||||
uploadLogs: true
|
||||
httpPort: 8080
|
||||
disableRateLimiting: true
|
||||
public_baseurl: "http://10.0.2.2:8080/"
|
||||
|
||||
- name: AVD cache
|
||||
uses: actions/cache@v3
|
||||
id: avd-cache
|
||||
with:
|
||||
path: |
|
||||
~/.android/avd/*
|
||||
~/.android/adb*
|
||||
key: avd-${{ matrix.api-level }}
|
||||
|
||||
- name: create AVD and generate snapshot for caching
|
||||
if: steps.avd-cache.outputs.cache-hit != 'true'
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
arch: x86
|
||||
profile: Nexus 5X
|
||||
force-avd-creation: true # Is set to false in the doc https://github.com/ReactiveCircus/android-emulator-runner
|
||||
emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
disable-animations: true
|
||||
script: echo "Generated AVD snapshot for caching."
|
||||
|
||||
- name: Run all the codecoverage tests at once
|
||||
uses: reactivecircus/android-emulator-runner@v2
|
||||
# continue-on-error: true
|
||||
with:
|
||||
api-level: ${{ matrix.api-level }}
|
||||
arch: x86
|
||||
profile: Nexus 5X
|
||||
force-avd-creation: false
|
||||
emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
disable-animations: true
|
||||
emulator-build: 7425822
|
||||
script: |
|
||||
./gradlew gatherGplayDebugStringTemplates $CI_GRADLE_ARG_PROPERTIES
|
||||
./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
||||
./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
||||
./gradlew generateCoverageReport $CI_GRADLE_ARG_PROPERTIES
|
||||
# NB: continue-on-error marks steps.tests.conclusion = 'success' but leaves steps.tests.outcome = 'failure'
|
||||
### - name: Run all the codecoverage tests at once (retry if emulator failed)
|
||||
### uses: reactivecircus/android-emulator-runner@v2
|
||||
### if: always() && steps.tests.outcome == 'failure' # don't run if previous step succeeded.
|
||||
### with:
|
||||
### api-level: 28
|
||||
### arch: x86
|
||||
### profile: Nexus 5X
|
||||
### force-avd-creation: false
|
||||
### emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
|
||||
### disable-animations: true
|
||||
### emulator-build: 7425822
|
||||
### script: |
|
||||
### ./gradlew gatherGplayDebugStringTemplates $CI_GRADLE_ARG_PROPERTIES
|
||||
### ./gradlew unitTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
||||
### ./gradlew instrumentationTestsWithCoverage $CI_GRADLE_ARG_PROPERTIES
|
||||
### ./gradlew generateCoverageReport $CI_GRADLE_ARG_PROPERTIES
|
||||
|
||||
- name: Upload Integration Test Report Log
|
||||
uses: actions/upload-artifact@v3
|
||||
if: always()
|
||||
with:
|
||||
name: integration-test-error-results
|
||||
path: |
|
||||
*/build/outputs/androidTest-results/connected/
|
||||
*/build/reports/androidTests/connected/
|
||||
|
||||
# we may have failed a previous step and retried, that's OK
|
||||
- name: Publish results to Sonar
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.SONARQUBE_GITHUB_API_TOKEN }} # Needed to get PR information, if any
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
ORG_GRADLE_PROJECT_SONAR_LOGIN: ${{ secrets.SONAR_TOKEN }}
|
||||
if: ${{ always() && env.GITHUB_TOKEN != '' && env.SONAR_TOKEN != '' && env.ORG_GRADLE_PROJECT_SONAR_LOGIN != '' }}
|
||||
run: ./gradlew sonarqube $CI_GRADLE_ARG_PROPERTIES
|
||||
|
||||
- name: Format unit test results
|
||||
if: always()
|
||||
run: python3 ./tools/ci/render_test_output.py unit ./**/build/test-results/**/*.xml
|
||||
|
||||
# can't be run on macos due to containers.
|
||||
# - name: Publish Unit Test Results
|
||||
# uses: EnricoMi/publish-unit-test-result-action@v1
|
||||
# if: always() &&
|
||||
# github.event.sender.login != 'dependabot[bot]' &&
|
||||
# ( github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository )
|
||||
# with:
|
||||
# files: ./**/build/test-results/**/*.xml
|
||||
|
||||
# Unneeded as part of the test suite above, kept around in case we want to re-enable them.
|
||||
#
|
||||
# # Build Android Tests
|
||||
# build-android-tests:
|
||||
# name: Build Android Tests
|
||||
# runs-on: ubuntu-latest
|
||||
# concurrency:
|
||||
# group: ${{ github.ref == 'refs/heads/main' && format('unit-tests-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('unit-tests-develop-{0}', github.sha) || format('build-android-tests-{0}', github.ref) }}
|
||||
# cancel-in-progress: true
|
||||
# steps:
|
||||
# - uses: actions/checkout@v3
|
||||
# - uses: actions/setup-java@v3
|
||||
# with:
|
||||
# distribution: 'adopt'
|
||||
# java-version: 11
|
||||
# - uses: actions/cache@v3
|
||||
# with:
|
||||
# path: |
|
||||
# ~/.gradle/caches
|
||||
# ~/.gradle/wrapper
|
||||
# key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
|
||||
# restore-keys: |
|
||||
# ${{ runner.os }}-gradle-
|
||||
# - name: Build Android Tests
|
||||
# run: ./gradlew clean assembleAndroidTest $CI_GRADLE_ARG_PROPERTIES
|
||||
|
17
.github/workflows/triage-incoming.yml
vendored
17
.github/workflows/triage-incoming.yml
vendored
@@ -1,17 +0,0 @@
|
||||
name: Move new issues onto Issue triage board
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
automate-project-columns:
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: github.repository == 'vector-im/element-android'
|
||||
steps:
|
||||
- uses: alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488
|
||||
with:
|
||||
project: Issue triage
|
||||
column: Incoming
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
248
.github/workflows/triage-labelled.yml
vendored
248
.github/workflows/triage-labelled.yml
vendored
@@ -1,248 +0,0 @@
|
||||
name: Move labelled issues to correct boards and columns
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
|
||||
jobs:
|
||||
apply_Z-Labs_label:
|
||||
name: Add Z-Labs label for features behind labs flags
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'A-Maths') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Pinning') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Polls') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Location-Sharing') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Bubbles') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-IA') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Themes-Custom') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Tags')
|
||||
steps:
|
||||
- uses: actions/github-script@v5
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ['Z-Labs']
|
||||
})
|
||||
|
||||
move_needs_info_issues:
|
||||
name: X-Needs-Info issues to Need info column on triage board
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: github.repository == 'vector-im/element-android'
|
||||
steps:
|
||||
- uses: konradpabjan/move-labeled-or-milestoned-issue@219d384e03fa4b6460cd24f9f37d19eb033a4338
|
||||
with:
|
||||
action-token: "${{ secrets.ELEMENT_BOT_TOKEN }}"
|
||||
project-url: "https://github.com/vector-im/element-android/projects/4"
|
||||
column-name: "Need info"
|
||||
label-name: "X-Needs-Info"
|
||||
|
||||
add_design_issues_to_project:
|
||||
name: X-Needs-Design to Design project board
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: >
|
||||
github.repository == 'vector-im/element-android' &&
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Design')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: add_to_project
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc0sUA"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
add_product_issues:
|
||||
name: X-Needs-Product to Design project board
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
contains(github.event.issue.labels.*.name, 'X-Needs-Product')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: add_to_project
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc4AAg6N"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
delight_issues_to_board:
|
||||
name: Spaces issues to Delight project board
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: >
|
||||
github.repository == 'vector-im/element-android' &&
|
||||
(contains(github.event.issue.labels.*.name, 'Team: Delight') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-AppLayout'))
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc1HvQ"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
move_voice-message_issues:
|
||||
name: A-Voice Messages to voice message board
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: >
|
||||
github.repository == 'vector-im/element-android' &&
|
||||
contains(github.event.issue.labels.*.name, 'A-Voice Messages')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc2KCw"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
move_message_bubbles_issues:
|
||||
name: A-Message-Bubbles to Message bubbles board
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: >
|
||||
github.repository == 'vector-im/element-android' &&
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Bubbles')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc3m-g"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
move_ftue_issues:
|
||||
name: Z-FTUE to Mobile FTUE board
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: >
|
||||
github.repository == 'vector-im/element-android' &&
|
||||
contains(github.event.issue.labels.*.name, 'Z-FTUE')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc4AAqVx"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
move_WTF_issues:
|
||||
name: Z-WTF to WTF board
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: >
|
||||
github.repository == 'vector-im/element-android' &&
|
||||
contains(github.event.issue.labels.*.name, 'Z-WTF')
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc4AArk0"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
move_element_x_issues:
|
||||
name: ElementX issues to ElementX project board
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: >
|
||||
github.repository == 'vector-im/element-android' &&
|
||||
(contains(github.event.issue.labels.*.name, 'Z-BBQ-Alpha') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-BBQ-Beta') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-BBQ-Release') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-Banquet-Alpha') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-Banquet-Beta') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-Banquet-Release'))
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!,$contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.issue.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc4ABTXY"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
143
.github/workflows/triage-move-review-requests.yml
vendored
143
.github/workflows/triage-move-review-requests.yml
vendored
@@ -1,143 +0,0 @@
|
||||
name: Move pull requests asking for review to the relevant project
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [review_requested]
|
||||
|
||||
jobs:
|
||||
add_design_pr_to_project:
|
||||
name: Move PRs asking for design review to the design board
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: github.repository == 'vector-im/element-android'
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: find_team_members
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
query find_team_members($team: String!) {
|
||||
organization(login: "vector-im") {
|
||||
team(slug: $team) {
|
||||
members {
|
||||
nodes {
|
||||
login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
team: ${{ env.TEAM }}
|
||||
env:
|
||||
TEAM: "design"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- id: any_matching_reviewers
|
||||
run: |
|
||||
# Fetch requested reviewers, and people who are on the team
|
||||
echo '${{ tojson(fromjson(steps.find_team_members.outputs.data).organization.team.members.nodes[*].login) }}' | tee /tmp/team_members.json
|
||||
echo '${{ tojson(github.event.pull_request.requested_reviewers[*].login) }}' | tee /tmp/reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_members.json | sort | tee /tmp/team_members.txt
|
||||
jq --raw-output .[] < /tmp/reviewers.json | sort | tee /tmp/reviewers.txt
|
||||
|
||||
# Fetch requested team reviewers, and the name of the team
|
||||
echo '${{ tojson(github.event.pull_request.requested_teams[*].slug) }}' | tee /tmp/team_reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_reviewers.json | sort | tee /tmp/team_reviewers.txt
|
||||
echo '${{ env.TEAM }}' | tee /tmp/team.txt
|
||||
|
||||
# If either a reviewer matches a team member, or a team matches our team, say "true"
|
||||
if [ $(join /tmp/team_members.txt /tmp/reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "::set-output name=match::true"
|
||||
elif [ $(join /tmp/team.txt /tmp/team_reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "::set-output name=match::true"
|
||||
else
|
||||
echo "::set-output name=match::false"
|
||||
fi
|
||||
env:
|
||||
TEAM: "design"
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: add_to_project
|
||||
if: steps.any_matching_reviewers.outputs.match == 'true'
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!, $contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.pull_request.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc0sUA"
|
||||
TEAM: "design"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
add_product_pr_to_project:
|
||||
name: Move PRs asking for product review to the product board
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: github.repository == 'vector-im/element-android'
|
||||
steps:
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: find_team_members
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
query find_team_members($team: String!) {
|
||||
organization(login: "vector-im") {
|
||||
team(slug: $team) {
|
||||
members {
|
||||
nodes {
|
||||
login
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
team: ${{ env.TEAM }}
|
||||
env:
|
||||
TEAM: "product"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
- id: any_matching_reviewers
|
||||
run: |
|
||||
# Fetch requested reviewers, and people who are on the team
|
||||
echo '${{ tojson(fromjson(steps.find_team_members.outputs.data).organization.team.members.nodes[*].login) }}' | tee /tmp/team_members.json
|
||||
echo '${{ tojson(github.event.pull_request.requested_reviewers[*].login) }}' | tee /tmp/reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_members.json | sort | tee /tmp/team_members.txt
|
||||
jq --raw-output .[] < /tmp/reviewers.json | sort | tee /tmp/reviewers.txt
|
||||
|
||||
# Fetch requested team reviewers, and the name of the team
|
||||
echo '${{ tojson(github.event.pull_request.requested_teams[*].slug) }}' | tee /tmp/team_reviewers.json
|
||||
jq --raw-output .[] < /tmp/team_reviewers.json | sort | tee /tmp/team_reviewers.txt
|
||||
echo '${{ env.TEAM }}' | tee /tmp/team.txt
|
||||
|
||||
# If either a reviewer matches a team member, or a team matches our team, say "true"
|
||||
if [ $(join /tmp/team_members.txt /tmp/reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "::set-output name=match::true"
|
||||
elif [ $(join /tmp/team.txt /tmp/team_reviewers.txt | wc -l) != 0 ]; then
|
||||
echo "::set-output name=match::true"
|
||||
else
|
||||
echo "::set-output name=match::false"
|
||||
fi
|
||||
env:
|
||||
TEAM: "product"
|
||||
- uses: octokit/graphql-action@v2.x
|
||||
id: add_to_project
|
||||
if: steps.any_matching_reviewers.outputs.match == 'true'
|
||||
with:
|
||||
headers: '{"GraphQL-Features": "projects_next_graphql"}'
|
||||
query: |
|
||||
mutation add_to_project($projectid:ID!, $contentid:ID!) {
|
||||
addProjectNextItem(input:{projectId:$projectid contentId:$contentid}) {
|
||||
projectNextItem {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
projectid: ${{ env.PROJECT_ID }}
|
||||
contentid: ${{ github.event.pull_request.node_id }}
|
||||
env:
|
||||
PROJECT_ID: "PN_kwDOAM0swc4AAg6N"
|
||||
TEAM: "product"
|
||||
GITHUB_TOKEN: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
57
.github/workflows/triage-priority-bugs.yml
vendored
57
.github/workflows/triage-priority-bugs.yml
vendored
@@ -1,57 +0,0 @@
|
||||
name: Move P1 bugs to boards
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled, unlabeled]
|
||||
|
||||
jobs:
|
||||
p1_issues_to_team_workboard:
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: >
|
||||
github.repository == 'vector-im/element-android' &&
|
||||
(!contains(github.event.issue.labels.*.name, 'A-E2EE') &&
|
||||
!contains(github.event.issue.labels.*.name, 'A-E2EE-Cross-Signing') &&
|
||||
!contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') &&
|
||||
!contains(github.event.issue.labels.*.name, 'A-E2EE-Key-Backup') &&
|
||||
!contains(github.event.issue.labels.*.name, 'A-E2EE-SAS-Verification')) &&
|
||||
(contains(github.event.issue.labels.*.name, 'T-Defect') &&
|
||||
contains(github.event.issue.labels.*.name, 'S-Critical') &&
|
||||
(contains(github.event.issue.labels.*.name, 'O-Frequent') ||
|
||||
contains(github.event.issue.labels.*.name, 'O-Occasional')) ||
|
||||
contains(github.event.issue.labels.*.name, 'S-Major') &&
|
||||
contains(github.event.issue.labels.*.name, 'O-Frequent') ||
|
||||
contains(github.event.issue.labels.*.name, 'A11y') &&
|
||||
contains(github.event.issue.labels.*.name, 'O-Frequent'))
|
||||
steps:
|
||||
- uses: alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488
|
||||
with:
|
||||
project: Android App Team
|
||||
column: Important Issues & Topics (P1)
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
P1_issues_to_crypto_team_workboard:
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: >
|
||||
github.repository == 'vector-im/element-android' &&
|
||||
(contains(github.event.issue.labels.*.name, 'Z-UISI') ||
|
||||
(contains(github.event.issue.labels.*.name, 'A-E2EE') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Cross-Signing') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Key-Backup') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-SAS-Verification')) &&
|
||||
(contains(github.event.issue.labels.*.name, 'T-Defect') &&
|
||||
contains(github.event.issue.labels.*.name, 'S-Critical') &&
|
||||
(contains(github.event.issue.labels.*.name, 'O-Frequent') ||
|
||||
contains(github.event.issue.labels.*.name, 'O-Occasional')) ||
|
||||
contains(github.event.issue.labels.*.name, 'S-Major') &&
|
||||
contains(github.event.issue.labels.*.name, 'O-Frequent') ||
|
||||
contains(github.event.issue.labels.*.name, 'A11y') &&
|
||||
contains(github.event.issue.labels.*.name, 'O-Frequent')))
|
||||
steps:
|
||||
- uses: alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488
|
||||
with:
|
||||
project: Crypto Team
|
||||
column: Ready
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
62
.github/workflows/triage-unlabelled.yml
vendored
62
.github/workflows/triage-unlabelled.yml
vendored
@@ -1,62 +0,0 @@
|
||||
name: Move unlabelled from needs info columns to triaged
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [unlabeled]
|
||||
|
||||
jobs:
|
||||
Move_Unabeled_Issue_On_Project_Board:
|
||||
name: Move no longer X-Needs-Info issues to Triaged
|
||||
runs-on: ubuntu-latest
|
||||
# Skip in forks
|
||||
if: >
|
||||
github.repository == 'vector-im/element-android' &&
|
||||
!contains(github.event.issue.labels.*.name, 'X-Needs-Info')
|
||||
env:
|
||||
BOARD_NAME: "Issue triage"
|
||||
OWNER: ${{ github.repository_owner }}
|
||||
REPO: ${{ github.event.repository.name }}
|
||||
ISSUE: ${{ github.event.issue.number }}
|
||||
steps:
|
||||
- name: Check if issue is already in "${{ env.BOARD_NAME }}"
|
||||
run: |
|
||||
if curl -i -H 'Content-Type: application/json' -H "Authorization: bearer ${{ secrets.GITHUB_TOKEN }}" -X POST -d '{"query": "query($issue: Int!, $owner: String!, $repo: String!) { repository(owner: $owner, name: $repo) { issue(number: $issue) { projectCards { nodes { project { name } } } } } } ", "variables" : "{ \"issue\": '${ISSUE}', \"owner\": \"'${OWNER}'\", \"repo\": \"'${REPO}'\" }" }' https://api.github.com/graphql | grep "\b$BOARD_NAME\b"; then
|
||||
echo "Issue is already in Project '$BOARD_NAME', proceeding";
|
||||
echo "ALREADY_IN_BOARD=true" >> $GITHUB_ENV
|
||||
else
|
||||
echo "Issue is not in project '$BOARD_NAME', cancelling this workflow"
|
||||
echo "ALREADY_IN_BOARD=false" >> $GITHUB_ENV
|
||||
fi
|
||||
- name: Move issue
|
||||
uses: alex-page/github-project-automation-plus@bb266ff4dde9242060e2d5418e120a133586d488
|
||||
if: ${{ env.ALREADY_IN_BOARD == 'true' }}
|
||||
with:
|
||||
project: Issue triage
|
||||
column: Triaged
|
||||
repo-token: ${{ secrets.ELEMENT_BOT_TOKEN }}
|
||||
|
||||
remove_Z-Labs_label:
|
||||
name: Remove Z-Labs label when features behind labs flags are removed
|
||||
runs-on: ubuntu-latest
|
||||
if: >
|
||||
!(contains(github.event.issue.labels.*.name, 'A-Maths') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Pinning') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Threads') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Polls') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Location-Sharing') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Message-Bubbles') ||
|
||||
contains(github.event.issue.labels.*.name, 'Z-IA') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Themes-Custom') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-E2EE-Dehydration') ||
|
||||
contains(github.event.issue.labels.*.name, 'A-Tags')) &&
|
||||
contains(github.event.issue.labels.*.name, 'Z-Labs')
|
||||
steps:
|
||||
- uses: actions/github-script@v5
|
||||
with:
|
||||
script: |
|
||||
github.rest.issues.removeLabel({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: ['Z-Labs']
|
||||
})
|
20
.github/workflows/update-gradle-wrapper.yml
vendored
20
.github/workflows/update-gradle-wrapper.yml
vendored
@@ -1,20 +0,0 @@
|
||||
name: Update Gradle Wrapper
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0 * * *"
|
||||
|
||||
jobs:
|
||||
update-gradle-wrapper:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Update Gradle Wrapper
|
||||
uses: gradle-update/update-gradle-wrapper-action@v1
|
||||
# Skip in forks
|
||||
if: github.repository == 'vector-im/element-android'
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
target-branch: develop
|
11
.gitignore
vendored
11
.gitignore
vendored
@@ -8,17 +8,10 @@
|
||||
.idea/*.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/benchmark-out
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
|
||||
/tmp
|
||||
/fastlane/private
|
||||
/fastlane/report.xml
|
||||
|
||||
/**/build
|
||||
|
||||
# Added by yarn
|
||||
/package.json
|
||||
/yarn.lock
|
||||
/node_modules
|
||||
ktlint
|
||||
.idea
|
||||
|
2
.idea/codeStyles/Project.xml
generated
2
.idea/codeStyles/Project.xml
generated
@@ -4,7 +4,7 @@
|
||||
<JetCodeStyleSettings>
|
||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||
<value>
|
||||
<package name="kotlinx.android.synthetic" alias="false" withSubpackages="true" />
|
||||
<package name="kotlinx.android.synthetic" withSubpackages="true" static="false" />
|
||||
</value>
|
||||
</option>
|
||||
<option name="ALIGN_IN_COLUMNS_CASE_BRANCH" value="true" />
|
||||
|
20
.idea/dictionaries/bmarty.xml
generated
20
.idea/dictionaries/bmarty.xml
generated
@@ -7,44 +7,24 @@
|
||||
<w>ciphertext</w>
|
||||
<w>coroutine</w>
|
||||
<w>decryptor</w>
|
||||
<w>displayname</w>
|
||||
<w>emoji</w>
|
||||
<w>emojis</w>
|
||||
<w>fdroid</w>
|
||||
<w>ganfra</w>
|
||||
<w>gplay</w>
|
||||
<w>hmac</w>
|
||||
<w>homeserver</w>
|
||||
<w>jitsi</w>
|
||||
<w>ktlint</w>
|
||||
<w>linkified</w>
|
||||
<w>linkify</w>
|
||||
<w>manu</w>
|
||||
<w>megolm</w>
|
||||
<w>msisdn</w>
|
||||
<w>msisdns</w>
|
||||
<w>pbkdf</w>
|
||||
<w>pids</w>
|
||||
<w>pkcs</w>
|
||||
<w>posthog</w>
|
||||
<w>previewable</w>
|
||||
<w>previewables</w>
|
||||
<w>pstn</w>
|
||||
<w>rageshake</w>
|
||||
<w>riotx</w>
|
||||
<w>signin</w>
|
||||
<w>signout</w>
|
||||
<w>signup</w>
|
||||
<w>snackbar</w>
|
||||
<w>ssss</w>
|
||||
<w>sygnal</w>
|
||||
<w>threepid</w>
|
||||
<w>uisi</w>
|
||||
<w>unifiedpush</w>
|
||||
<w>unpublish</w>
|
||||
<w>unwedging</w>
|
||||
<w>vctr</w>
|
||||
<w>wellknown</w>
|
||||
</words>
|
||||
</dictionary>
|
||||
</component>
|
BIN
.idea/icon.png
generated
BIN
.idea/icon.png
generated
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
1
.idea/sqldelight/matrix-sdk-sqldelight/.sqldelight
generated
Normal file
1
.idea/sqldelight/matrix-sdk-sqldelight/.sqldelight
generated
Normal file
@@ -0,0 +1 @@
|
||||
{"databases":[{"packageName":"im.vector.matrix.sqldelight.auth","compilationUnits":[{"name":"main","sourceFolders":[{"path":"src/main/sqldelight/auth","dependency":false}]}],"outputDirectory":"build/generated/sqldelight/code/AuthDatabase","className":"AuthDatabase","dependencies":[]},{"packageName":"im.vector.matrix.sqldelight.crypto","compilationUnits":[{"name":"main","sourceFolders":[{"path":"src/main/sqldelight/crypto","dependency":false}]}],"outputDirectory":"build/generated/sqldelight/code/CryptoDatabase","className":"CryptoDatabase","dependencies":[]},{"packageName":"im.vector.matrix.sqldelight.session","compilationUnits":[{"name":"main","sourceFolders":[{"path":"src/main/sqldelight/session","dependency":false}]}],"outputDirectory":"build/generated/sqldelight/code/SessionDatabase","className":"SessionDatabase","dependencies":[]}]}
|
60
.travis.yml
Normal file
60
.travis.yml
Normal file
@@ -0,0 +1,60 @@
|
||||
# FTR: Configuration on https://travis-ci.org/vector-im/riotX-android/settings
|
||||
#
|
||||
# - Build only if .travis.yml is present -> On
|
||||
# - Limit concurrent jobs -> Off
|
||||
# - Build pushed branches -> On (build the branch)
|
||||
# - Build pushed pull request -> On (build the PR after auto-merge)
|
||||
#
|
||||
# - Auto cancel branch builds -> On
|
||||
# - Auto cancel pull request builds -> On
|
||||
|
||||
language: android
|
||||
jdk: oraclejdk8
|
||||
sudo: false
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
|
||||
android:
|
||||
components:
|
||||
# Uncomment the lines below if you want to
|
||||
# use the latest revision of Android SDK Tools
|
||||
- tools
|
||||
- platform-tools
|
||||
|
||||
# The BuildTools version used by your project
|
||||
- build-tools-29.0.3
|
||||
|
||||
# The SDK version used to compile your project
|
||||
- android-29
|
||||
|
||||
before_cache:
|
||||
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
|
||||
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
|
||||
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.gradle/caches/
|
||||
- $HOME/.gradle/wrapper/
|
||||
- $HOME/.android/build-cache
|
||||
|
||||
# Build with the development SDK
|
||||
before_script:
|
||||
# Not necessary for the moment
|
||||
# - /bin/sh ./set_debug_env.sh
|
||||
|
||||
# Just build the project for now
|
||||
script:
|
||||
# Build app (assembleGplayRelease assembleFdroidRelease)
|
||||
# Build Android test (assembleAndroidTest) (disabled for now)
|
||||
# Code quality (lintGplayRelease lintFdroidRelease)
|
||||
# Split into two steps because if a task contain Fdroid, PlayService will be disabled
|
||||
# Done by Buildkite now: - ./gradlew clean assembleGplayRelease lintGplayRelease --stacktrace
|
||||
# Done by Buildkite now: - ./gradlew clean assembleFdroidRelease lintFdroidRelease --stacktrace
|
||||
# Run unitary test (Disable for now, see https://travis-ci.org/vector-im/riot-android/builds/502504370)
|
||||
# - ./gradlew testGplayReleaseUnitTest --stacktrace
|
||||
# Other code quality check
|
||||
# Done by Buildkite now: - ./tools/check/check_code_quality.sh
|
||||
- ./tools/travis/check_pr.sh
|
||||
# Check that indonesians file are identical. Due to Android issue, the resource folder must be value-in/, and Weblate export data into value-id/.
|
||||
# Done by Buildkite now: - diff ./vector/src/main/res/values-id/strings.xml ./vector/src/main/res/values-in/strings.xml
|
22
AUTHORS.md
22
AUTHORS.md
@@ -1,10 +1,10 @@
|
||||
A full developer contributors list can be found [here](https://github.com/vector-im/element-android/graphs/contributors).
|
||||
A full developer contributors list can be found [here](https://github.com/vector-im/riotX-android/graphs/contributors).
|
||||
|
||||
# Core team:
|
||||
|
||||
Even if we try to be able to work on all the functionalities, we have more knowledge about what we have developed ourselves.
|
||||
|
||||
## [Benoit](https://github.com/bmarty): Android team leader
|
||||
## Benoit: Android team leader
|
||||
|
||||
[@benoit.marty:matrix.org](https://matrix.to/#/@benoit.marty:matrix.org)
|
||||
- Android team leader and project leader, Android developer, GitHub community manager.
|
||||
@@ -12,7 +12,7 @@ Even if we try to be able to work on all the functionalities, we have more knowl
|
||||
- Reviewing and polishing developed features, code quality manager, PRs reviewer, GitHub community manager.
|
||||
- Release manager on the Play Store
|
||||
|
||||
## [Ganfra](https://github.com/ganfra) (aka François): Software architect
|
||||
## François: Software architect
|
||||
|
||||
[@ganfra:matrix.org](https://matrix.to/#/@ganfra:matrix.org)
|
||||
- Software architect, Android developer
|
||||
@@ -20,26 +20,16 @@ Even if we try to be able to work on all the functionalities, we have more knowl
|
||||
- Work mainly on the global architecture of the project.
|
||||
- Specialist of the timeline, and lots of other features.
|
||||
|
||||
## [Valere](https://github.com/BillCarsonFr): Product manager, Android developer
|
||||
## Valere: Product manager, Android developer
|
||||
|
||||
[@valere35:matrix.org](https://matrix.to/#/@valere35:matrix.org)
|
||||
- Product manager, Android developer
|
||||
- Specialist on the crypto implementation.
|
||||
|
||||
## [Onuray](https://github.com/onurays): Android developer
|
||||
|
||||
[@onurays:matrix.org](https://matrix.to/#/@onurays:matrix.org)
|
||||
- Android developer
|
||||
|
||||
# Other contributors
|
||||
|
||||
First of all, we thank all contributors who use Element and report problems on this GitHub project or via the integrated rageshake function.
|
||||
First of all, we thank all contributors who use RiotX and report problems on this GitHub project or via the integrated rageshake function.
|
||||
|
||||
We do not forget all translators, for their work of translating Element into many languages. They are also the authors of Element.
|
||||
We do not forget all translators, for their work of translating RiotX into many languages. They are also the authors of RiotX.
|
||||
|
||||
Feel free to add your name below, when you contribute to the project!
|
||||
|
||||
Name | Matrix ID | GitHub
|
||||
----------|-----------------------------|--------------------------------------
|
||||
gjpower | @gjpower:matrix.org | [gjpower](https://github.com/gjpower)
|
||||
TR_SLimey | @tr_slimey:an-atom-in.space | [TR-SLimey](https://github.com/TR-SLimey)
|
||||
|
2500
CHANGES.md
2500
CHANGES.md
File diff suppressed because it is too large
Load Diff
@@ -2,50 +2,30 @@
|
||||
|
||||
Please read https://github.com/matrix-org/synapse/blob/master/CONTRIBUTING.md
|
||||
|
||||
Element Android support can be found in this room: [](https://matrix.to/#/#element-android:matrix.org).
|
||||
Android support can be found in this [](https://matrix.to/#/#riot-android:matrix.org) room.
|
||||
|
||||
Dedicated room for RiotX: [](https://matrix.to/#/#riotx:matrix.org)
|
||||
|
||||
# Specific rules for Matrix Android projects
|
||||
|
||||
## Android Studio settings
|
||||
|
||||
Please set the "hard wrap" setting of Android Studio to 160 chars, this is the setting we use internally to format the source code (Menu `Settings/Editor/Code Style` then `Hard wrap at`).
|
||||
Please ensure that you're using the project formatting rules (which are in the project at .idea/codeStyles/), and format the file before committing them.
|
||||
|
||||
### Template
|
||||
|
||||
An Android Studio template has been added to the project to help creating all files needed when adding a new screen to the application. Fragment, ViewModel, Activity, etc.
|
||||
|
||||
To install the template (to be done only once):
|
||||
- Go to folder `./tools/template`.
|
||||
- Mac OSX: Run the script `./configure.sh`.
|
||||
|
||||
Linux: Run `ANDROID_STUDIO=/path/to/android-studio ./configure`
|
||||
- e.g. `ANDROID_STUDIO=/usr/local/android-studio ./configure`
|
||||
|
||||
- Restart Android Studio.
|
||||
|
||||
To create a new screen:
|
||||
- First create a new package in your code.
|
||||
- Then right click on the package, and select `New/New Vector/Element Feature`.
|
||||
- Follow the Wizard, especially replace `Main` by something more relevant to your feature.
|
||||
- Click on `Finish`.
|
||||
- Remaining steps are described as TODO in the generated files, or will be pointed out by the compiler, or at runtime :)
|
||||
|
||||
Note that if the templates are modified, the only things to do is to restart Android Studio for the change to take effect.
|
||||
Please ensure that your using the project formatting rules (which are in the project at .idea/codeStyles/), and format the file before committing them.
|
||||
|
||||
## Compilation
|
||||
|
||||
For now, the Matrix SDK and the Element application are in the same project. So there is no specific thing to do, this project should compile without any special action.
|
||||
For now, the Matrix SDK and the RiotX application are in the same project. So there is no specific thing to do, this project should compile without any special action.
|
||||
|
||||
## I want to help translating Element
|
||||
## I want to help translating RiotX
|
||||
|
||||
If you want to fix an issue with an English string, please submit a PR.
|
||||
If you want to fix an issue in other languages, or add a missing translation, or even add a new language, please use [Weblate](https://translate.element.io/projects/element-android/).
|
||||
If you want to fix an issue in other languages, or add a missing translation, or even add a new language, please use [Weblate](https://translate.riot.im/projects/riot-android/).
|
||||
|
||||
For the moment, Strings from Riot will be used, there is no dedicated project in Weblate for RiotX.
|
||||
|
||||
## I want to submit a PR to fix an issue
|
||||
|
||||
Please have a look in the [dedicated documentation](./docs/pull_request.md) about pull request.
|
||||
|
||||
Please check if a corresponding issue exists. If yes, please let us know in a comment that you're working on it.
|
||||
If an issue does not exist yet, it may be relevant to open a new issue and let us know that you're implementing it.
|
||||
|
||||
@@ -53,22 +33,9 @@ If an issue does not exist yet, it may be relevant to open a new issue and let u
|
||||
|
||||
This project is full Kotlin. Please do not write Java classes.
|
||||
|
||||
### Changelog
|
||||
### CHANGES.md
|
||||
|
||||
Please create at least one file under ./changelog.d containing details about your change. Towncrier will be used when preparing the release.
|
||||
|
||||
Towncrier says to use the PR number for the filename, but the issue number is also fine.
|
||||
|
||||
Supported filename extensions are:
|
||||
|
||||
- ``.feature``: Signifying a new feature in Element Android or in the Matrix SDK.
|
||||
- ``.bugfix``: Signifying a bug fix.
|
||||
- ``.wip``: Signifying a work in progress change, typically a component of a larger feature which will be enabled once all tasks are complete.
|
||||
- ``.doc``: Signifying a documentation improvement.
|
||||
- ``.sdk``: Signifying a change to the Matrix SDK, this could be an addition, deprecation or removal of a public API.
|
||||
- ``.misc``: Any other changes.
|
||||
|
||||
See https://github.com/twisted/towncrier#news-fragments if you need more details.
|
||||
Please add a line to the top of the file `CHANGES.md` describing your change.
|
||||
|
||||
### Code quality
|
||||
|
||||
@@ -83,13 +50,14 @@ Make sure the following commands execute without any error:
|
||||
#### ktlint
|
||||
|
||||
<pre>
|
||||
./gradlew ktlintCheck --continue
|
||||
curl -sSLO https://github.com/pinterest/ktlint/releases/download/0.34.2/ktlint && chmod a+x ktlint
|
||||
./ktlint --android --experimental -v
|
||||
</pre>
|
||||
|
||||
Note that you can run
|
||||
|
||||
<pre>
|
||||
./gradlew ktlintFormat
|
||||
./ktlint --android --experimental -v -F
|
||||
</pre>
|
||||
|
||||
For ktlint to fix some detected errors for you (you still have to check and commit the fix of course)
|
||||
@@ -111,57 +79,26 @@ Make sure the following commands execute without any error:
|
||||
|
||||
### Tests
|
||||
|
||||
Element is currently supported on Android Lollipop (API 21+): please test your change on an Android device (or Android emulator) running with API 21. Many issues can happen (including crashes) on older devices.
|
||||
RiotX is currently supported on Android KitKat (API 19+): please test your change on an Android device (or Android emulator) running with API 19. Many issues can happen (including crashes) on older devices.
|
||||
Also, if possible, please test your change on a real device. Testing on Android emulator may not be sufficient.
|
||||
|
||||
You should consider adding Unit tests with your PR, and also integration tests (AndroidTest). Please refer to [this document](./docs/integration_tests.md) to install and run the integration test environment.
|
||||
|
||||
### Internationalisation
|
||||
|
||||
Translations are handled using an external tool: [Weblate](https://translate.element.io/projects/element-android/)
|
||||
|
||||
As a general rule, please never edit or add or remove translations to the project in a Pull Request. It can lead to merge conflict if the translations are also modified in Weblate side.
|
||||
|
||||
#### Adding new string
|
||||
|
||||
When adding new string resources, please only add new entries in the file `value/strings.xml`. Translations will be added later by the community of translators using Weblate.
|
||||
|
||||
The file `value/strings.xml` must only contain American English (U. S. English) values, as this is the default language of the Android operating system. So for instance, please use "color" instead of "colour". Element Android will still use the language set on the system by the user, like any other Android applications which provide translations. The system language can be any other English language variants, or any other languages. Note that this is also possible to override the system language using the Element Android in-app language settings.
|
||||
|
||||
New strings can be added anywhere in the file `value/strings.xml`, not necessarily at the end of the file. Generally, it's even better to add the new strings in some dedicated section per feature, and not at the end of the file, to avoid merge conflict between 2 PR adding strings at the end of the same file.
|
||||
|
||||
When adding new string resources, please only add new entries in file `value/strings.xml`. Translations will be added later by the community of translators with a specific tool named [Weblate](https://translate.riot.im/projects/riot-android/).
|
||||
Do not hesitate to use plurals when appropriate.
|
||||
|
||||
#### Editing existing strings
|
||||
|
||||
Two cases:
|
||||
- If the meaning stays the same, it's OK to edit the original string (i.e. the English version).
|
||||
- If the meaning is not the same, please create a new string and do not remove the existing string. See below for instructions to remove existing string.
|
||||
|
||||
#### Removing existing strings
|
||||
|
||||
If a string is not used anymore, it should be removed from the resource, but please do not remove the strings or its translations in the PR. It can lead to merge conflict with Weblate, and to lint error if new translations from deleted strings are added with Weblate.
|
||||
|
||||
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
|
||||
|
||||
Please consider accessibility as an important point. As a minimum requirement, in layout XML files please use attributes such as `android:contentDescription` and `android:importantForAccessibility`, and test with a screen reader if it's working well. You can add new string resources, dedicated to accessibility, in this case, please prefix theirs id with `a11y_`.
|
||||
|
||||
For instance, when updating the image `src` of an ImageView, please also consider updating its `contentDescription`. A good example is a play pause button.
|
||||
|
||||
### Layout
|
||||
|
||||
When adding or editing layouts, make sure the layout will render correctly if device uses a RTL (Right To Left) language.
|
||||
You can check this in the layout editor preview by selecting any RTL language (ex: Arabic).
|
||||
|
||||
Also please check that the colors are ok for all the current themes of Element. Please use `?attr` instead of `@color` to reference colors in the layout. You can check this in the layout editor preview by selecting all the main themes (`AppTheme.Status`, `AppTheme.Dark`, etc.).
|
||||
Also please check that the colors are ok for all the current themes of RiotX. Please use `?attr` instead of `@color` to reference colors in the layout. You can check this in the layout editor preview by selecting all the main themes (`AppTheme.Status`, `AppTheme.Dark`, etc.).
|
||||
|
||||
### Authors
|
||||
|
||||
|
248
Gemfile.lock
248
Gemfile.lock
@@ -1,248 +0,0 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.3)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
artifactory (3.0.15)
|
||||
atomos (0.1.3)
|
||||
aws-eventstream (1.1.1)
|
||||
aws-partitions (1.479.0)
|
||||
aws-sdk-core (3.117.0)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
aws-partitions (~> 1, >= 1.239.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
jmespath (~> 1.0)
|
||||
aws-sdk-kms (1.44.0)
|
||||
aws-sdk-core (~> 3, >= 3.112.0)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sdk-s3 (1.96.1)
|
||||
aws-sdk-core (~> 3, >= 3.112.0)
|
||||
aws-sdk-kms (~> 1)
|
||||
aws-sigv4 (~> 1.1)
|
||||
aws-sigv4 (1.2.4)
|
||||
aws-eventstream (~> 1, >= 1.0.2)
|
||||
babosa (1.0.4)
|
||||
claide (1.0.3)
|
||||
claide-plugins (0.9.2)
|
||||
cork
|
||||
nap
|
||||
open4 (~> 1.3)
|
||||
colored (1.2)
|
||||
colored2 (3.1.2)
|
||||
commander (4.6.0)
|
||||
highline (~> 2.0.0)
|
||||
cork (0.3.0)
|
||||
colored2 (~> 3.1)
|
||||
danger (8.6.1)
|
||||
claide (~> 1.0)
|
||||
claide-plugins (>= 0.9.2)
|
||||
colored2 (~> 3.1)
|
||||
cork (~> 0.1)
|
||||
faraday (>= 0.9.0, < 2.0)
|
||||
faraday-http-cache (~> 2.0)
|
||||
git (~> 1.7)
|
||||
kramdown (~> 2.3)
|
||||
kramdown-parser-gfm (~> 1.0)
|
||||
no_proxy_fix
|
||||
octokit (~> 4.7)
|
||||
terminal-table (>= 1, < 4)
|
||||
declarative (0.0.20)
|
||||
digest-crc (0.6.3)
|
||||
rake (>= 12.0.0, < 14.0.0)
|
||||
domain_name (0.5.20190701)
|
||||
unf (>= 0.0.5, < 1.0.0)
|
||||
dotenv (2.7.6)
|
||||
emoji_regex (3.2.2)
|
||||
excon (0.85.0)
|
||||
faraday (1.5.1)
|
||||
faraday-em_http (~> 1.0)
|
||||
faraday-em_synchrony (~> 1.0)
|
||||
faraday-excon (~> 1.1)
|
||||
faraday-httpclient (~> 1.0.1)
|
||||
faraday-net_http (~> 1.0)
|
||||
faraday-net_http_persistent (~> 1.1)
|
||||
faraday-patron (~> 1.0)
|
||||
multipart-post (>= 1.2, < 3)
|
||||
ruby2_keywords (>= 0.0.4)
|
||||
faraday-cookie_jar (0.0.7)
|
||||
faraday (>= 0.8.0)
|
||||
http-cookie (~> 1.0.0)
|
||||
faraday-em_http (1.0.0)
|
||||
faraday-em_synchrony (1.0.0)
|
||||
faraday-excon (1.1.0)
|
||||
faraday-http-cache (2.4.0)
|
||||
faraday (>= 0.8)
|
||||
faraday-httpclient (1.0.1)
|
||||
faraday-net_http (1.0.1)
|
||||
faraday-net_http_persistent (1.2.0)
|
||||
faraday-patron (1.0.0)
|
||||
faraday_middleware (1.0.0)
|
||||
faraday (~> 1.0)
|
||||
fastimage (2.2.4)
|
||||
fastlane (2.187.0)
|
||||
CFPropertyList (>= 2.3, < 4.0.0)
|
||||
addressable (>= 2.3, < 3.0.0)
|
||||
artifactory (~> 3.0)
|
||||
aws-sdk-s3 (~> 1.0)
|
||||
babosa (>= 1.0.3, < 2.0.0)
|
||||
bundler (>= 1.12.0, < 3.0.0)
|
||||
colored
|
||||
commander (~> 4.6)
|
||||
dotenv (>= 2.1.1, < 3.0.0)
|
||||
emoji_regex (>= 0.1, < 4.0)
|
||||
excon (>= 0.71.0, < 1.0.0)
|
||||
faraday (~> 1.0)
|
||||
faraday-cookie_jar (~> 0.0.6)
|
||||
faraday_middleware (~> 1.0)
|
||||
fastimage (>= 2.1.0, < 3.0.0)
|
||||
gh_inspector (>= 1.1.2, < 2.0.0)
|
||||
google-apis-androidpublisher_v3 (~> 0.1)
|
||||
google-apis-playcustomapp_v1 (~> 0.1)
|
||||
google-cloud-storage (~> 1.31)
|
||||
highline (~> 2.0)
|
||||
json (< 3.0.0)
|
||||
jwt (>= 2.1.0, < 3)
|
||||
mini_magick (>= 4.9.4, < 5.0.0)
|
||||
multipart-post (~> 2.0.0)
|
||||
naturally (~> 2.2)
|
||||
plist (>= 3.1.0, < 4.0.0)
|
||||
rubyzip (>= 2.0.0, < 3.0.0)
|
||||
security (= 0.1.3)
|
||||
simctl (~> 1.6.3)
|
||||
terminal-notifier (>= 2.0.0, < 3.0.0)
|
||||
terminal-table (>= 1.4.5, < 2.0.0)
|
||||
tty-screen (>= 0.6.3, < 1.0.0)
|
||||
tty-spinner (>= 0.8.0, < 1.0.0)
|
||||
word_wrap (~> 1.0.0)
|
||||
xcodeproj (>= 1.13.0, < 2.0.0)
|
||||
xcpretty (~> 0.3.0)
|
||||
xcpretty-travis-formatter (>= 0.0.3)
|
||||
gh_inspector (1.1.3)
|
||||
git (1.11.0)
|
||||
rchardet (~> 1.8)
|
||||
google-apis-androidpublisher_v3 (0.8.0)
|
||||
google-apis-core (>= 0.4, < 2.a)
|
||||
google-apis-core (0.4.0)
|
||||
addressable (~> 2.5, >= 2.5.1)
|
||||
googleauth (>= 0.16.2, < 2.a)
|
||||
httpclient (>= 2.8.1, < 3.a)
|
||||
mini_mime (~> 1.0)
|
||||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.a)
|
||||
rexml
|
||||
webrick
|
||||
google-apis-iamcredentials_v1 (0.6.0)
|
||||
google-apis-core (>= 0.4, < 2.a)
|
||||
google-apis-playcustomapp_v1 (0.5.0)
|
||||
google-apis-core (>= 0.4, < 2.a)
|
||||
google-apis-storage_v1 (0.6.0)
|
||||
google-apis-core (>= 0.4, < 2.a)
|
||||
google-cloud-core (1.6.0)
|
||||
google-cloud-env (~> 1.0)
|
||||
google-cloud-errors (~> 1.0)
|
||||
google-cloud-env (1.5.0)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
google-cloud-errors (1.1.0)
|
||||
google-cloud-storage (1.34.1)
|
||||
addressable (~> 2.5)
|
||||
digest-crc (~> 0.4)
|
||||
google-apis-iamcredentials_v1 (~> 0.1)
|
||||
google-apis-storage_v1 (~> 0.1)
|
||||
google-cloud-core (~> 1.6)
|
||||
googleauth (>= 0.16.2, < 2.a)
|
||||
mini_mime (~> 1.0)
|
||||
googleauth (0.16.2)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
memoist (~> 0.16)
|
||||
multi_json (~> 1.11)
|
||||
os (>= 0.9, < 2.0)
|
||||
signet (~> 0.14)
|
||||
highline (2.0.3)
|
||||
http-cookie (1.0.4)
|
||||
domain_name (~> 0.5)
|
||||
httpclient (2.8.3)
|
||||
jmespath (1.4.0)
|
||||
json (2.5.1)
|
||||
jwt (2.2.3)
|
||||
kramdown (2.4.0)
|
||||
rexml
|
||||
kramdown-parser-gfm (1.1.0)
|
||||
kramdown (~> 2.0)
|
||||
memoist (0.16.2)
|
||||
mini_magick (4.11.0)
|
||||
mini_mime (1.1.0)
|
||||
multi_json (1.15.0)
|
||||
multipart-post (2.0.0)
|
||||
nanaimo (0.3.0)
|
||||
nap (1.1.0)
|
||||
naturally (2.2.1)
|
||||
no_proxy_fix (0.1.2)
|
||||
octokit (4.25.1)
|
||||
faraday (>= 1, < 3)
|
||||
sawyer (~> 0.9)
|
||||
open4 (1.3.4)
|
||||
os (1.1.1)
|
||||
plist (3.6.0)
|
||||
public_suffix (4.0.6)
|
||||
rake (13.0.6)
|
||||
rchardet (1.8.0)
|
||||
representable (3.1.1)
|
||||
declarative (< 0.1.0)
|
||||
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||
uber (< 0.2.0)
|
||||
retriable (3.1.2)
|
||||
rexml (3.2.5)
|
||||
rouge (2.0.7)
|
||||
ruby2_keywords (0.0.5)
|
||||
rubyzip (2.3.2)
|
||||
sawyer (0.9.2)
|
||||
addressable (>= 2.3.5)
|
||||
faraday (>= 0.17.3, < 3)
|
||||
security (0.1.3)
|
||||
signet (0.15.0)
|
||||
addressable (~> 2.3)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.5, < 3.0)
|
||||
multi_json (~> 1.10)
|
||||
simctl (1.6.8)
|
||||
CFPropertyList
|
||||
naturally
|
||||
terminal-notifier (2.0.0)
|
||||
terminal-table (1.8.0)
|
||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||
trailblazer-option (0.1.1)
|
||||
tty-cursor (0.7.1)
|
||||
tty-screen (0.8.1)
|
||||
tty-spinner (0.9.3)
|
||||
tty-cursor (~> 0.7)
|
||||
uber (0.1.0)
|
||||
unf (0.1.4)
|
||||
unf_ext
|
||||
unf_ext (0.0.7.7)
|
||||
unicode-display_width (1.7.0)
|
||||
webrick (1.7.0)
|
||||
word_wrap (1.0.0)
|
||||
xcodeproj (1.20.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
rexml (~> 3.2.4)
|
||||
xcpretty (0.3.0)
|
||||
rouge (~> 2.0.7)
|
||||
xcpretty-travis-formatter (1.0.1)
|
||||
xcpretty (~> 0.2, >= 0.0.7)
|
||||
|
||||
PLATFORMS
|
||||
universal-darwin-21
|
||||
x86_64-darwin-20
|
||||
|
||||
DEPENDENCIES
|
||||
danger
|
||||
fastlane
|
||||
|
||||
BUNDLED WITH
|
||||
2.2.15
|
58
README.md
58
README.md
@@ -1,56 +1,38 @@
|
||||
[](https://buildkite.com/matrix-dot-org/element-android/builds?branch=develop)
|
||||
[](https://translate.element.io/engage/element-android/?utm_source=widget)
|
||||
[](https://matrix.to/#/#element-android:matrix.org)
|
||||
[](https://sonarcloud.io/summary/new_code?id=vector-im_element-android)
|
||||
[](https://sonarcloud.io/summary/new_code?id=vector-im_element-android)
|
||||
[](https://sonarcloud.io/summary/new_code?id=vector-im_element-android)
|
||||
[](https://buildkite.com/matrix-dot-org/riotx-android/builds?branch=develop)
|
||||
[](https://translate.riot.im/engage/riot-android/?utm_source=widget)
|
||||
[](https://matrix.to/#/#riotx:matrix.org)
|
||||
[](https://sonarcloud.io/dashboard?id=vector.android.riotx)
|
||||
[](https://sonarcloud.io/dashboard?id=vector.android.riotx)
|
||||
[](https://sonarcloud.io/dashboard?id=vector.android.riotx)
|
||||
|
||||
# Element Android
|
||||
# RiotX Android
|
||||
|
||||
Element Android is an Android Matrix Client provided by [Element](https://element.io/). The app can be run on every Android devices with Android OS Lollipop and more (API 21).
|
||||
RiotX is an Android Matrix Client currently in beta but in active development.
|
||||
|
||||
It is a total rewrite of [Riot-Android](https://github.com/vector-im/riot-android) with a new user experience.
|
||||
It is a total rewrite of [Riot-Android](https://github.com/vector-im/riot-android) with a new user experience. RiotX will become the official replacement as soon as all features are implemented.
|
||||
|
||||
[<img src="resources/img/google-play-badge.png" alt="Get it on Google Play" height="60">](https://play.google.com/store/apps/details?id=im.vector.app)
|
||||
[<img src="resources/img/f-droid-badge.png" alt="Get it on F-Droid" height="60">](https://f-droid.org/app/im.vector.app)
|
||||
|
||||
Nightly build: [](https://buildkite.com/matrix-dot-org/element-android/builds?branch=develop) Nightly test status: [](https://github.com/vector-im/element-android/actions/workflows/nightly.yml)
|
||||
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" alt="Get it on Google Play" height="60">](https://play.google.com/store/apps/details?id=im.vector.riotx)
|
||||
[<img src="https://f-droid.org/badge/get-it-on.png" alt="Get it on F-Droid" height="60">](https://f-droid.org/app/im.vector.riotx)
|
||||
|
||||
Nightly build: [](https://buildkite.com/matrix-dot-org/riotx-android/builds?branch=develop)
|
||||
|
||||
# New Android SDK
|
||||
|
||||
Element is based on a new Android SDK fully written in Kotlin (like Element). In order to make the early development as fast as possible, Element and the new SDK currently share the same git repository.
|
||||
RiotX is based on a new Android SDK fully written in Kotlin (like RiotX). In order to make the early development as fast as possible, RiotX and the new SDK currently share the same git repository. We will make separate repos once the SDK is stable enough.
|
||||
|
||||
At each Element release, the SDK module is copied to a dedicated repository: https://github.com/matrix-org/matrix-android-sdk2. That way, third party apps can add a regular gradle dependency to use it. So more details on how to do that here: https://github.com/matrix-org/matrix-android-sdk2.
|
||||
|
||||
# Roadmap
|
||||
|
||||
The version 1.0.0 of Element still misses some features which was previously included in Riot-Android.
|
||||
The team will work to add them on a regular basis.
|
||||
The current target is to release an application out of beta with the same level of features (and even more) as Riot.
|
||||
The roadmap has 3 phases:
|
||||
|
||||
# Releases to app stores
|
||||
- [phase 0](https://github.com/vector-im/riotX-android/labels/phase0): Prototyping / Project setup
|
||||
- [phase 1](https://github.com/vector-im/riotX-android/labels/phase1): Beta release to the Play Store
|
||||
- [phase 2](https://github.com/vector-im/riotX-android/labels/phase2): Out of beta
|
||||
|
||||
There is some delay between when a release is created and when it appears in the app stores (Google Play Store and F-Droid). Here are some of the reasons:
|
||||
|
||||
* Not all versioned releases that appear on GitHub are considered stable. Each release is first considered beta: this continues for at least two days. If the release is stable (no serious issues or crashes are reported), then it is released as a production release in Google Play Store, and a request is sent to F-Droid too.
|
||||
* Each release on the Google Play Store undergoes review by Google before it comes out. This can take an unpredictable amount of time. In some cases it has taken several weeks.
|
||||
* In order for F-Droid to guarantee that the app you receive exactly matches the public source code, they build releases themselves. When a release is considered stable, Element staff inform the F-Droid maintainers and it is added to the build queue. Depending on the load on F-Droid's infrastructure, it can take some time for releases to be built. This always takes at least 24 hours, and can take several days.
|
||||
|
||||
If you would like to receive releases more quickly (bearing in mind that they may not be stable) you have a number of options:
|
||||
|
||||
1. [Sign up to receive beta releases](https://play.google.com/apps/testing/im.vector.app) via the Google Play Store.
|
||||
2. Install a [release APK](https://github.com/vector-im/element-android/releases) directly - download the relevant .apk file and allow installing from untrusted sources in your device settings. Note: these releases are the Google Play version, which depend on some Google services. If you prefer to avoid that, try the latest dev builds, and choose the F-Droid version.
|
||||
3. If you're really brave, install the [very latest dev build](https://buildkite.com/matrix-dot-org/element-android/builds/latest?branch=develop&state=passed) - click on *Assemble (GPlay or FDroid) Debug version* then on *Artifacts*.
|
||||
|
||||
## Contributing
|
||||
|
||||
Please refer to [CONTRIBUTING.md](https://github.com/vector-im/element-android/blob/develop/CONTRIBUTING.md) if you want to contribute on Matrix Android projects!
|
||||
|
||||
Come chat with the community in the dedicated Matrix [room](https://matrix.to/#/#element-android:matrix.org).
|
||||
|
||||
## Triaging issues
|
||||
|
||||
Issues are triaged by community members and the Android App Team, following the [triage process](https://github.com/vector-im/element-meta/wiki/Triage-process).
|
||||
|
||||
We use [issue labels](https://github.com/vector-im/element-meta/wiki/Issue-labelling) to sort all incoming issues.
|
||||
Please refer to [CONTRIBUTING.md](https://github.com/vector-im/riotX-android/blob/develop/CONTRIBUTING.md) if you want to contribute on Matrix Android projects!
|
||||
|
||||
Come chat with the community in the dedicated Matrix [room](https://matrix.to/#/#riotx:matrix.org).
|
||||
|
264
build.gradle
264
build.gradle
@@ -1,206 +1,85 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
apply from: 'dependencies.gradle'
|
||||
apply from: 'dependencies_groups.gradle'
|
||||
|
||||
ext.kotlin_version = '1.3.50'
|
||||
repositories {
|
||||
// Do not use `google()`, it prevents Dependabot from working properly
|
||||
maven {
|
||||
url 'https://maven.google.com'
|
||||
}
|
||||
google()
|
||||
jcenter()
|
||||
maven {
|
||||
url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
// Do not use `mavenCentral()`, it prevents Dependabot from working properly
|
||||
maven {
|
||||
url 'https://repo1.maven.org/maven2'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Release notes of Android Gradle Plugin (AGP):
|
||||
// https://developer.android.com/studio/releases/gradle-plugin
|
||||
classpath libs.gradle.gradlePlugin
|
||||
classpath libs.gradle.kotlinPlugin
|
||||
classpath libs.gradle.hiltPlugin
|
||||
classpath 'com.google.firebase:firebase-appdistribution-gradle:3.0.3'
|
||||
classpath 'com.google.gms:google-services:4.3.13'
|
||||
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:3.4.0.2513'
|
||||
classpath 'com.google.android.gms:oss-licenses-plugin:0.10.5'
|
||||
classpath "com.likethesalad.android:stem-plugin:2.2.2"
|
||||
classpath 'org.owasp:dependency-check-gradle:7.2.0'
|
||||
classpath "org.jetbrains.dokka:dokka-gradle-plugin:1.7.10"
|
||||
classpath "org.jetbrains.kotlinx:kotlinx-knit:0.4.0"
|
||||
classpath 'com.jakewharton:butterknife-gradle-plugin:10.2.3'
|
||||
classpath 'com.android.tools.build:gradle:3.5.3'
|
||||
classpath 'com.google.gms:google-services:4.3.2'
|
||||
classpath "com.airbnb.okreplay:gradle-plugin:1.5.0"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
classpath 'org.sonarsource.scanner.gradle:sonarqube-gradle-plugin:2.7.1'
|
||||
classpath 'com.google.android.gms:oss-licenses-plugin:0.9.5'
|
||||
classpath 'com.squareup.sqldelight:gradle-plugin:1.2.2'
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
// ktlint Plugin
|
||||
id "org.jlleitschuh.gradle.ktlint" version "11.0.0"
|
||||
// Detekt
|
||||
id "io.gitlab.arturbosch.detekt" version "1.21.0"
|
||||
|
||||
// Dependency Analysis
|
||||
id 'com.autonomousapps.dependency-analysis' version "1.13.1"
|
||||
}
|
||||
|
||||
// https://github.com/jeremylong/DependencyCheck
|
||||
apply plugin: 'org.owasp.dependencycheck'
|
||||
|
||||
dependencyCheck {
|
||||
// See https://jeremylong.github.io/DependencyCheck/general/suppression.html
|
||||
suppressionFiles = [
|
||||
"./tools/dependencycheck/suppressions.xml"
|
||||
]
|
||||
}
|
||||
|
||||
allprojects {
|
||||
apply plugin: "org.jlleitschuh.gradle.ktlint"
|
||||
apply plugin: "io.gitlab.arturbosch.detekt"
|
||||
|
||||
repositories {
|
||||
// Do not use `mavenCentral()`, it prevents Dependabot from working properly
|
||||
maven {
|
||||
url 'https://repo1.maven.org/maven2'
|
||||
content {
|
||||
groups.mavenCentral.regex.each { includeGroupByRegex it }
|
||||
groups.mavenCentral.group.each { includeGroup it }
|
||||
}
|
||||
}
|
||||
// For olm library. This has to be declared first, to ensure that Olm library is not downloaded from another repo
|
||||
maven {
|
||||
url 'https://jitpack.io'
|
||||
content {
|
||||
groups.jitpack.regex.each { includeGroupByRegex it }
|
||||
groups.jitpack.group.each { includeGroup it }
|
||||
// Use this repo only for olm library
|
||||
includeGroupByRegex "org\\.matrix\\.gitlab\\.matrix-org"
|
||||
// And also for FilePicker
|
||||
includeGroupByRegex "com\\.github\\.jaiselrahman"
|
||||
// And monarchy
|
||||
includeGroupByRegex "com\\.github\\.Zhuinden"
|
||||
// And ucrop
|
||||
includeGroupByRegex "com\\.github\\.yalantis"
|
||||
// JsonViewer
|
||||
includeGroupByRegex 'com\\.github\\.BillCarsonFr'
|
||||
}
|
||||
}
|
||||
// Jitsi repo
|
||||
maven {
|
||||
url "https://github.com/vector-im/jitsi_libre_maven/raw/main/android-sdk-5.0.2"
|
||||
// Note: to test Jitsi release you can use a local file like this:
|
||||
// url "file:///Users/bmarty/workspaces/jitsi_libre_maven/android-sdk-3.10.0"
|
||||
url "http://dl.bintray.com/piasy/maven"
|
||||
content {
|
||||
groups.jitsi.regex.each { includeGroupByRegex it }
|
||||
groups.jitsi.group.each { includeGroup it }
|
||||
}
|
||||
}
|
||||
// Do not use `google()`, it prevents Dependabot from working properly
|
||||
maven {
|
||||
url 'https://maven.google.com'
|
||||
content {
|
||||
groups.google.regex.each { includeGroupByRegex it }
|
||||
groups.google.group.each { includeGroup it }
|
||||
}
|
||||
}
|
||||
//noinspection JcenterRepositoryObsolete
|
||||
// Do not use `jcenter`, it prevents Dependabot from working properly
|
||||
maven {
|
||||
url 'https://jcenter.bintray.com'
|
||||
content {
|
||||
groups.jcenter.regex.each { includeGroupByRegex it }
|
||||
groups.jcenter.group.each { includeGroup it }
|
||||
includeGroupByRegex "com\\.github\\.piasy"
|
||||
}
|
||||
}
|
||||
maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
|
||||
google()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
|
||||
// Warnings are potential errors, so stop ignoring them
|
||||
// You can override by passing `-PallWarningsAsErrors=false` in the command line
|
||||
kotlinOptions.allWarningsAsErrors = project.getProperties().getOrDefault("allWarningsAsErrors", "true").toBoolean()
|
||||
kotlinOptions.allWarningsAsErrors = false
|
||||
}
|
||||
|
||||
// Fix "Java heap space" issue
|
||||
tasks.withType(org.jlleitschuh.gradle.ktlint.tasks.BaseKtLintCheckTask).configureEach {
|
||||
it.workerMaxHeapSize.set("2G")
|
||||
}
|
||||
|
||||
// See https://github.com/JLLeitschuh/ktlint-gradle#configuration
|
||||
ktlint {
|
||||
// See https://github.com/pinterest/ktlint/releases/
|
||||
version = "0.45.1"
|
||||
android = true
|
||||
ignoreFailures = false
|
||||
enableExperimentalRules = true
|
||||
// display the corresponding rule
|
||||
verbose = true
|
||||
reporters {
|
||||
reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.PLAIN)
|
||||
// To have XML report for Danger
|
||||
reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.CHECKSTYLE)
|
||||
}
|
||||
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",
|
||||
"experimental:annotation",
|
||||
// - Missing newline after "("
|
||||
// - Missing newline before ")"
|
||||
"wrapping",
|
||||
// - Unnecessary trailing comma before ")"
|
||||
"experimental:trailing-comma",
|
||||
// - A block comment in between other elements on the same line is disallowed
|
||||
"experimental:comment-wrapping",
|
||||
// - A KDoc comment after any other element on the same line must be separated by a new line
|
||||
"experimental:kdoc-wrapping",
|
||||
// Ignore error "Redundant curly braces", since we use it to fix false positives, for instance in "elementLogs.${i}.txt"
|
||||
"string-template",
|
||||
]
|
||||
}
|
||||
|
||||
detekt {
|
||||
// preconfigure defaults
|
||||
buildUponDefaultConfig = true
|
||||
// activate all available (even unstable) rules.
|
||||
allRules = true
|
||||
// point to your custom config defining rules to run, overwriting default behavior
|
||||
config = files("$rootDir/tools/detekt/detekt.yml")
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
|
||||
def launchTask = getGradle()
|
||||
.getStartParameter()
|
||||
.getTaskRequests()
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
|
||||
if (launchTask.contains("coverage".toLowerCase())) {
|
||||
apply from: 'coverage.gradle'
|
||||
}
|
||||
|
||||
apply plugin: 'org.sonarqube'
|
||||
|
||||
// To run a sonar analysis:
|
||||
// Run './gradlew sonarqube -Dsonar.login=<REPLACE_WITH_SONAR_KEY>'
|
||||
// The SONAR_KEY is stored in passbolt as Token Sonar Cloud Bma
|
||||
// The SONAR_KEY is stored in passbolt
|
||||
|
||||
sonarqube {
|
||||
properties {
|
||||
property "sonar.projectName", "element-android"
|
||||
property "sonar.projectKey", "vector-im_element-android"
|
||||
property "sonar.projectName", "RiotX-Android"
|
||||
property "sonar.projectKey", "vector.android.riotx"
|
||||
property "sonar.host.url", "https://sonarcloud.io"
|
||||
property "sonar.projectVersion", project(":vector").android.defaultConfig.versionName
|
||||
property "sonar.sourceEncoding", "UTF-8"
|
||||
property "sonar.links.homepage", "https://github.com/vector-im/element-android/"
|
||||
property "sonar.links.ci", "https://github.com/vector-im/element-android/actions"
|
||||
property "sonar.links.scm", "https://github.com/vector-im/element-android/"
|
||||
property "sonar.links.issue", "https://github.com/vector-im/element-android/issues"
|
||||
property "sonar.links.homepage", "https://github.com/vector-im/riotX-android/"
|
||||
property "sonar.links.ci", "https://buildkite.com/matrix-dot-org/riotx-android"
|
||||
property "sonar.links.scm", "https://github.com/vector-im/riotX-android/"
|
||||
property "sonar.links.issue", "https://github.com/vector-im/riotX-android/issues"
|
||||
property "sonar.organization", "new_vector_ltd_organization"
|
||||
property "sonar.java.coveragePlugin", "jacoco"
|
||||
property "sonar.coverage.jacoco.xmlReportPaths", "${project.buildDir}/reports/jacoco/generateCoverageReport/generateCoverageReport.xml"
|
||||
property "sonar.login", project.hasProperty("SONAR_LOGIN") ? SONAR_LOGIN : "invalid"
|
||||
}
|
||||
}
|
||||
@@ -210,18 +89,11 @@ project(":vector") {
|
||||
properties {
|
||||
property "sonar.sources", project(":vector").android.sourceSets.main.java.srcDirs
|
||||
// exclude source code from analyses separated by a colon (:)
|
||||
// Exclude Java source
|
||||
property "sonar.exclusions", "**/BugReporterMultipartBody.java"
|
||||
// property "sonar.exclusions", "**/*.*"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project(":library:diff-match-patch") {
|
||||
sonarqube {
|
||||
skipProject = true
|
||||
}
|
||||
}
|
||||
|
||||
//project(":matrix-sdk-android") {
|
||||
// sonarqube {
|
||||
// properties {
|
||||
@@ -231,59 +103,13 @@ project(":library:diff-match-patch") {
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
dependencyAnalysis {
|
||||
dependencies {
|
||||
bundle("kotlin-stdlib") {
|
||||
includeGroup("org.jetbrains.kotlin")
|
||||
}
|
||||
bundle("react") {
|
||||
includeGroup("com.facebook.react")
|
||||
}
|
||||
}
|
||||
issues {
|
||||
all {
|
||||
ignoreKtx(true)
|
||||
onUsedTransitiveDependencies {
|
||||
// Transitively used dependencies that should be declared directly
|
||||
severity("ignore")
|
||||
}
|
||||
onUnusedDependencies {
|
||||
severity("fail")
|
||||
}
|
||||
onUnusedAnnotationProcessors {
|
||||
severity("fail")
|
||||
exclude("com.airbnb.android:epoxy-processor", "com.google.dagger:hilt-compiler") // False positives
|
||||
}
|
||||
}
|
||||
project(":library:jsonviewer") {
|
||||
onUnusedDependencies {
|
||||
exclude("org.json:json") // Used in unit tests, overwrites the one bundled into Android
|
||||
}
|
||||
}
|
||||
project(":library:ui-styles")
|
||||
project(":matrix-sdk-android") {
|
||||
onUnusedDependencies {
|
||||
exclude("io.reactivex.rxjava2:rxkotlin") // Transitively required for mocking realm as monarchy doesn't expose Rx
|
||||
}
|
||||
}
|
||||
project(":matrix-sdk-android-flow") {
|
||||
onUnusedDependencies {
|
||||
exclude("androidx.paging:paging-runtime-ktx") // False positive
|
||||
}
|
||||
}
|
||||
project(":vector") {
|
||||
onUnusedDependencies {
|
||||
// False positives
|
||||
exclude(
|
||||
"androidx.fragment:fragment-testing",
|
||||
"com.facebook.soloader:soloader",
|
||||
"com.vanniktech:emoji-google",
|
||||
"com.vanniktech:emoji-material",
|
||||
"org.maplibre.gl:android-plugin-annotation-v9",
|
||||
"org.maplibre.gl:android-sdk",
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
//project(":matrix-sdk-android-rx") {
|
||||
// sonarqube {
|
||||
// properties {
|
||||
// property "sonar.sources", project(":matrix-sdk-android-rx").android.sourceSets.main.java.srcDirs
|
||||
// // exclude source code from analyses separated by a colon (:)
|
||||
// // property "sonar.exclusions", "**/*.*"
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
1
changelog.d/.gitignore
vendored
1
changelog.d/.gitignore
vendored
@@ -1 +0,0 @@
|
||||
!.gitignore
|
@@ -1 +0,0 @@
|
||||
Fix text margin in QR code view when no display name is set
|
@@ -1 +0,0 @@
|
||||
[App Layout] Recents carousel now scrolled to first position when new item added to or moved to this position
|
@@ -1 +0,0 @@
|
||||
[Modules] Lifts the application variants to the app module
|
@@ -1 +0,0 @@
|
||||
Create DM room only on first message - Add a spinner when sending the first message
|
@@ -1 +0,0 @@
|
||||
Ensure that we do not expect all the Event fields when requesting `rooms/{roomId}/hierarchy` endpoint.
|
@@ -1 +0,0 @@
|
||||
[Device Manager] Filter Other Sessions
|
@@ -1 +0,0 @@
|
||||
[Device management] Session details screen
|
@@ -1 +0,0 @@
|
||||
Fixed problem when room list's scroll did jump after rooms placeholders were replaced with rooms summary items
|
@@ -1 +0,0 @@
|
||||
Fixes crash when quickly double clicking FABs in the new app layout
|
@@ -1 +0,0 @@
|
||||
Fixes space list and new chat bottom sheets showing too small in New App Layout (especially evident in landscape)
|
@@ -1 +0,0 @@
|
||||
Move some GitHub actions to buildjet runners, and remove the second attempt to run integration tests.
|
@@ -1 +0,0 @@
|
||||
Create DM room only on first message - Fix glitch in the room list
|
@@ -1 +0,0 @@
|
||||
[App Layout] Room leaving prompt dialog now waits user to confirm leaving before do so
|
@@ -1 +0,0 @@
|
||||
Fix empty verification bottom sheet.
|
@@ -1 +0,0 @@
|
||||
[New Layout] Fixes new chat dialog not getting dismissed after selecting its actions
|
@@ -1 +0,0 @@
|
||||
Exclude legacy android support annotation library
|
@@ -1 +0,0 @@
|
||||
Pulling no longer hosted im.dlg:android-dialer directly into the repository and removing legacy support library usages
|
@@ -1 +0,0 @@
|
||||
Create DM room only on first message - Handle the local rooms within the new AppLayout
|
@@ -1 +0,0 @@
|
||||
Fixing build cache misses when compiling the vector module
|
@@ -1 +0,0 @@
|
||||
New App Layout is now enabled by default! Go to the Settings > Labs to toggle this
|
@@ -1,91 +0,0 @@
|
||||
def excludes = [
|
||||
// dependency injection graph
|
||||
'**/*Module.*',
|
||||
'**/*Module*.*',
|
||||
|
||||
// Framework entry points
|
||||
'**/*Activity*',
|
||||
'**/*Fragment*',
|
||||
'**/*Application*',
|
||||
'**/*AndroidService*',
|
||||
|
||||
// We would like to exclude android widgets as well but our naming is inconsistent
|
||||
|
||||
// Proof of concept
|
||||
'**/*Login2*',
|
||||
|
||||
// Generated
|
||||
'**/*JsonAdapter*',
|
||||
'**/*Item.*',
|
||||
'**/*$Holder.*',
|
||||
'**/*ViewHolder.*',
|
||||
'**/*View.*',
|
||||
'**/*BottomSheet.*'
|
||||
]
|
||||
|
||||
def initializeReport(report, projects, classExcludes) {
|
||||
projects.each { project -> project.apply plugin: 'jacoco' }
|
||||
|
||||
report.executionData {
|
||||
fileTree(rootProject.rootDir.absolutePath).include(
|
||||
"**/build/**/*.exec",
|
||||
"**/build/outputs/code_coverage/**/coverage.ec",
|
||||
)
|
||||
}
|
||||
report.reports {
|
||||
xml.enabled true
|
||||
html.enabled true
|
||||
csv.enabled false
|
||||
}
|
||||
|
||||
gradle.projectsEvaluated {
|
||||
def androidSourceDirs = []
|
||||
def androidClassDirs = []
|
||||
|
||||
projects.each { project ->
|
||||
switch (project) {
|
||||
case { project.plugins.hasPlugin("com.android.application") }:
|
||||
androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/gplayDebug")
|
||||
androidSourceDirs.add("${project.projectDir}/src/main/kotlin")
|
||||
androidSourceDirs.add("${project.projectDir}/src/main/java")
|
||||
break
|
||||
case { project.plugins.hasPlugin("com.android.library") }:
|
||||
androidClassDirs.add("${project.buildDir}/tmp/kotlin-classes/debug")
|
||||
androidSourceDirs.add("${project.projectDir}/src/main/kotlin")
|
||||
androidSourceDirs.add("${project.projectDir}/src/main/java")
|
||||
break
|
||||
default:
|
||||
report.sourceSets project.sourceSets.main
|
||||
}
|
||||
}
|
||||
|
||||
report.sourceDirectories.setFrom(report.sourceDirectories + files(androidSourceDirs))
|
||||
def classFiles = androidClassDirs.collect { files(it).files }.flatten()
|
||||
report.classDirectories.setFrom(files((report.classDirectories.files + classFiles).collect {
|
||||
fileTree(dir: it, excludes: classExcludes)
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
def collectProjects(predicate) {
|
||||
return subprojects.findAll { it.buildFile.isFile() && predicate(it) }
|
||||
}
|
||||
|
||||
task generateCoverageReport(type: JacocoReport) {
|
||||
outputs.upToDateWhen { false }
|
||||
rootProject.apply plugin: 'jacoco'
|
||||
def projects = collectProjects { ['vector-app', 'vector', 'matrix-sdk-android'].contains(it.name) }
|
||||
initializeReport(it, projects, excludes)
|
||||
}
|
||||
|
||||
task unitTestsWithCoverage(type: GradleBuild) {
|
||||
// the 7.1.3 android gradle plugin has a bug where enableTestCoverage generates invalid coverage
|
||||
startParameter.projectProperties.coverage = [enableTestCoverage: false]
|
||||
tasks = ['testDebugUnitTest']
|
||||
}
|
||||
|
||||
task instrumentationTestsWithCoverage(type: GradleBuild) {
|
||||
startParameter.projectProperties.coverage = [enableTestCoverage: true]
|
||||
startParameter.projectProperties['android.testInstrumentationRunnerArguments.notPackage'] = 'im.vector.app.ui'
|
||||
tasks = [':vector-app:connectedGplayDebugAndroidTest', ':vector:connectedDebugAndroidTest', 'matrix-sdk-android:connectedDebugAndroidTest']
|
||||
}
|
@@ -1,175 +0,0 @@
|
||||
ext.versions = [
|
||||
|
||||
'minSdk' : 21,
|
||||
'compileSdk' : 31,
|
||||
'targetSdk' : 31,
|
||||
'sourceCompat' : JavaVersion.VERSION_11,
|
||||
'targetCompat' : JavaVersion.VERSION_11,
|
||||
]
|
||||
|
||||
|
||||
// Pinned to 7.1.3 because of https://github.com/vector-im/element-android/issues/6142
|
||||
// Please test carefully before upgrading again.
|
||||
def gradle = "7.1.3"
|
||||
// Ref: https://kotlinlang.org/releases.html
|
||||
def kotlin = "1.6.21"
|
||||
def kotlinCoroutines = "1.6.4"
|
||||
def dagger = "2.42"
|
||||
def appDistribution = "16.0.0-beta04"
|
||||
def retrofit = "2.9.0"
|
||||
def arrow = "0.8.2"
|
||||
def markwon = "4.6.2"
|
||||
def moshi = "1.13.0"
|
||||
def lifecycle = "2.5.1"
|
||||
def flowBinding = "1.2.0"
|
||||
def flipper = "0.164.0"
|
||||
def epoxy = "4.6.2"
|
||||
def mavericks = "2.7.0"
|
||||
def glide = "4.13.2"
|
||||
def bigImageViewer = "1.8.1"
|
||||
def jjwt = "0.11.5"
|
||||
def vanniktechEmoji = "0.15.0"
|
||||
|
||||
def fragment = "1.5.2"
|
||||
|
||||
// Testing
|
||||
def mockk = "1.12.3" // We need to use 1.12.3 to have mocking in androidTest until a new version is released: https://github.com/mockk/mockk/issues/819
|
||||
def espresso = "3.4.0"
|
||||
def androidxTest = "1.4.0"
|
||||
def androidxOrchestrator = "1.4.1"
|
||||
ext.libs = [
|
||||
gradle : [
|
||||
'gradlePlugin' : "com.android.tools.build:gradle:$gradle",
|
||||
'kotlinPlugin' : "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin",
|
||||
'hiltPlugin' : "com.google.dagger:hilt-android-gradle-plugin:$dagger"
|
||||
|
||||
],
|
||||
jetbrains : [
|
||||
'coroutinesCore' : "org.jetbrains.kotlinx:kotlinx-coroutines-core:$kotlinCoroutines",
|
||||
'coroutinesAndroid' : "org.jetbrains.kotlinx:kotlinx-coroutines-android:$kotlinCoroutines",
|
||||
'coroutinesTest' : "org.jetbrains.kotlinx:kotlinx-coroutines-test:$kotlinCoroutines"
|
||||
],
|
||||
androidx : [
|
||||
'activity' : "androidx.activity:activity:1.5.1",
|
||||
'appCompat' : "androidx.appcompat:appcompat:1.4.2",
|
||||
'biometric' : "androidx.biometric:biometric:1.1.0",
|
||||
'core' : "androidx.core:core-ktx:1.8.0",
|
||||
'recyclerview' : "androidx.recyclerview:recyclerview:1.2.1",
|
||||
'exifinterface' : "androidx.exifinterface:exifinterface:1.3.3",
|
||||
'fragmentKtx' : "androidx.fragment:fragment-ktx:$fragment",
|
||||
'fragmentTesting' : "androidx.fragment:fragment-testing:$fragment",
|
||||
'constraintLayout' : "androidx.constraintlayout:constraintlayout:2.1.4",
|
||||
'work' : "androidx.work:work-runtime-ktx:2.7.1",
|
||||
'autoFill' : "androidx.autofill:autofill:1.1.0",
|
||||
'preferenceKtx' : "androidx.preference:preference-ktx:1.2.0",
|
||||
'junit' : "androidx.test.ext:junit:1.1.3",
|
||||
'lifecycleCommon' : "androidx.lifecycle:lifecycle-common:$lifecycle",
|
||||
'lifecycleLivedata' : "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle",
|
||||
'lifecycleProcess' : "androidx.lifecycle:lifecycle-process:$lifecycle",
|
||||
'lifecycleRuntimeKtx' : "androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle",
|
||||
'datastore' : "androidx.datastore:datastore:1.0.0",
|
||||
'datastorepreferences' : "androidx.datastore:datastore-preferences:1.0.0",
|
||||
'pagingRuntimeKtx' : "androidx.paging:paging-runtime-ktx:2.1.2",
|
||||
'coreTesting' : "androidx.arch.core:core-testing:2.1.0",
|
||||
'testCore' : "androidx.test:core:$androidxTest",
|
||||
'orchestrator' : "androidx.test:orchestrator:$androidxOrchestrator",
|
||||
'testRunner' : "androidx.test:runner:$androidxTest",
|
||||
'testRules' : "androidx.test:rules:$androidxTest",
|
||||
'espressoCore' : "androidx.test.espresso:espresso-core:$espresso",
|
||||
'espressoContrib' : "androidx.test.espresso:espresso-contrib:$espresso",
|
||||
'espressoIntents' : "androidx.test.espresso:espresso-intents:$espresso",
|
||||
'viewpager2' : "androidx.viewpager2:viewpager2:1.0.0",
|
||||
'transition' : "androidx.transition:transition:1.2.0",
|
||||
],
|
||||
google : [
|
||||
'material' : "com.google.android.material:material:1.6.1",
|
||||
'appdistributionApi' : "com.google.firebase:firebase-appdistribution-api-ktx:$appDistribution",
|
||||
'appdistribution' : "com.google.firebase:firebase-appdistribution:$appDistribution",
|
||||
// Phone number https://github.com/google/libphonenumber
|
||||
'phonenumber' : "com.googlecode.libphonenumber:libphonenumber:8.12.55"
|
||||
],
|
||||
dagger : [
|
||||
'dagger' : "com.google.dagger:dagger:$dagger",
|
||||
'daggerCompiler' : "com.google.dagger:dagger-compiler:$dagger",
|
||||
'hilt' : "com.google.dagger:hilt-android:$dagger",
|
||||
'hiltAndroidTesting' : "com.google.dagger:hilt-android-testing:$dagger",
|
||||
'hiltCompiler' : "com.google.dagger:hilt-compiler:$dagger"
|
||||
],
|
||||
flipper : [
|
||||
'flipper' : "com.facebook.flipper:flipper:$flipper",
|
||||
'flipperNetworkPlugin' : "com.facebook.flipper:flipper-network-plugin:$flipper",
|
||||
],
|
||||
element : [
|
||||
'opusencoder' : "io.element.android:opusencoder:1.0.4",
|
||||
],
|
||||
squareup : [
|
||||
'moshi' : "com.squareup.moshi:moshi:$moshi",
|
||||
'moshiKt' : "com.squareup.moshi:moshi-kotlin:$moshi",
|
||||
'moshiKotlin' : "com.squareup.moshi:moshi-kotlin-codegen:$moshi",
|
||||
'moshiAdapters' : "com.squareup.moshi:moshi-adapters:$moshi",
|
||||
'retrofit' : "com.squareup.retrofit2:retrofit:$retrofit",
|
||||
'retrofitMoshi' : "com.squareup.retrofit2:converter-moshi:$retrofit"
|
||||
],
|
||||
rx : [
|
||||
'rxKotlin' : "io.reactivex.rxjava2:rxkotlin:2.4.0"
|
||||
],
|
||||
arrow : [
|
||||
'core' : "io.arrow-kt:arrow-core:$arrow",
|
||||
'instances' : "io.arrow-kt:arrow-instances-core:$arrow"
|
||||
],
|
||||
markwon : [
|
||||
'core' : "io.noties.markwon:core:$markwon",
|
||||
'extLatex' : "io.noties.markwon:ext-latex:$markwon",
|
||||
'inlineParser' : "io.noties.markwon:inline-parser:$markwon",
|
||||
'html' : "io.noties.markwon:html:$markwon"
|
||||
],
|
||||
airbnb : [
|
||||
'epoxy' : "com.airbnb.android:epoxy:$epoxy",
|
||||
'epoxyGlide' : "com.airbnb.android:epoxy-glide-preloading:$epoxy",
|
||||
'epoxyProcessor' : "com.airbnb.android:epoxy-processor:$epoxy",
|
||||
'epoxyPaging' : "com.airbnb.android:epoxy-paging:$epoxy",
|
||||
'mavericks' : "com.airbnb.android:mavericks:$mavericks",
|
||||
'mavericksTesting' : "com.airbnb.android:mavericks-testing:$mavericks"
|
||||
],
|
||||
maplibre : [
|
||||
'androidSdk' : "org.maplibre.gl:android-sdk:9.5.2",
|
||||
'pluginAnnotation' : "org.maplibre.gl:android-plugin-annotation-v9:1.0.0"
|
||||
],
|
||||
mockk : [
|
||||
'mockk' : "io.mockk:mockk:$mockk",
|
||||
'mockkAndroid' : "io.mockk:mockk-android:$mockk"
|
||||
],
|
||||
github : [
|
||||
'glide' : "com.github.bumptech.glide:glide:$glide",
|
||||
'glideCompiler' : "com.github.bumptech.glide:compiler:$glide",
|
||||
'bigImageViewer' : "com.github.piasy:BigImageViewer:$bigImageViewer",
|
||||
'glideImageLoader' : "com.github.piasy:GlideImageLoader:$bigImageViewer",
|
||||
'progressPieIndicator' : "com.github.piasy:ProgressPieIndicator:$bigImageViewer",
|
||||
'glideImageViewFactory' : "com.github.piasy:GlideImageViewFactory:$bigImageViewer",
|
||||
'flowBinding' : "io.github.reactivecircus.flowbinding:flowbinding-android:$flowBinding",
|
||||
'flowBindingAppcompat' : "io.github.reactivecircus.flowbinding:flowbinding-appcompat:$flowBinding",
|
||||
'flowBindingMaterial' : "io.github.reactivecircus.flowbinding:flowbinding-material:$flowBinding"
|
||||
],
|
||||
jakewharton : [
|
||||
'timber' : "com.jakewharton.timber:timber:5.0.1"
|
||||
],
|
||||
jsonwebtoken: [
|
||||
'jjwtApi' : "io.jsonwebtoken:jjwt-api:$jjwt",
|
||||
'jjwtImpl' : "io.jsonwebtoken:jjwt-impl:$jjwt",
|
||||
'jjwtOrgjson' : "io.jsonwebtoken:jjwt-orgjson:$jjwt"
|
||||
],
|
||||
vanniktech : [
|
||||
'emojiMaterial' : "com.vanniktech:emoji-material:$vanniktechEmoji",
|
||||
'emojiGoogle' : "com.vanniktech:emoji-google:$vanniktechEmoji"
|
||||
],
|
||||
apache : [
|
||||
'commonsImaging' : "org.apache.sanselan:sanselan:0.97-incubator"
|
||||
],
|
||||
tests : [
|
||||
'kluent' : "org.amshove.kluent:kluent-android:1.68",
|
||||
'timberJunitRule' : "net.lachlanmckee:timber-junit-rule:1.0.1",
|
||||
'junit' : "junit:junit:4.13.2"
|
||||
]
|
||||
]
|
||||
|
||||
|
@@ -1,226 +0,0 @@
|
||||
ext.groups = [
|
||||
jitpack : [
|
||||
regex: [
|
||||
],
|
||||
group: [
|
||||
'com.github.Armen101',
|
||||
'com.github.chrisbanes',
|
||||
'com.github.hyuwah',
|
||||
'com.github.jetradarmobile',
|
||||
'com.github.MatrixFrog',
|
||||
'com.github.tapadoo',
|
||||
'com.github.UnifiedPush',
|
||||
'com.github.vector-im',
|
||||
'com.github.yalantis',
|
||||
'com.github.Zhuinden',
|
||||
]
|
||||
],
|
||||
jitsi : [
|
||||
regex: [
|
||||
],
|
||||
group: [
|
||||
'com.facebook.react',
|
||||
'org.jitsi.react',
|
||||
'org.webkit',
|
||||
]
|
||||
],
|
||||
google : [
|
||||
regex: [
|
||||
'androidx\\..*',
|
||||
'com\\.android\\.tools\\..*',
|
||||
'com\\.google\\.android\\..*',
|
||||
],
|
||||
group: [
|
||||
'com.android',
|
||||
'com.android.ndk.thirdparty',
|
||||
'com.android.tools',
|
||||
'com.google.firebase',
|
||||
'com.google.testing.platform',
|
||||
]
|
||||
],
|
||||
mavenCentral: [
|
||||
regex: [
|
||||
],
|
||||
group: [
|
||||
'ch.qos.logback',
|
||||
'com.adevinta.android',
|
||||
'com.airbnb.android',
|
||||
'com.almworks.sqlite4java',
|
||||
'com.arthenica',
|
||||
'com.atlassian.commonmark',
|
||||
'com.atlassian.pom',
|
||||
'com.beust',
|
||||
'com.davemorrissey.labs',
|
||||
'com.dropbox.core',
|
||||
'com.soywiz.korlibs.korte',
|
||||
'com.facebook.fbjni',
|
||||
'com.facebook.flipper',
|
||||
'com.facebook.fresco',
|
||||
'com.facebook.infer.annotation',
|
||||
'com.facebook.soloader',
|
||||
'com.facebook.stetho',
|
||||
'com.facebook.yoga',
|
||||
'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',
|
||||
'com.github.javaparser',
|
||||
'com.github.piasy',
|
||||
'com.github.shyiko.klob',
|
||||
'com.github.rubensousa',
|
||||
'com.google',
|
||||
'com.google.android',
|
||||
'com.google.api.grpc',
|
||||
'com.google.auto.service',
|
||||
'com.google.auto.value',
|
||||
'com.google.code.findbugs',
|
||||
'com.google.code.gson',
|
||||
'com.google.dagger',
|
||||
'com.google.devtools.ksp',
|
||||
'com.google.errorprone',
|
||||
'com.google.googlejavaformat',
|
||||
'com.google.guava',
|
||||
'com.google.j2objc',
|
||||
'com.google.jimfs',
|
||||
'com.google.protobuf',
|
||||
'com.google.zxing',
|
||||
'com.googlecode.htmlcompressor',
|
||||
'com.googlecode.json-simple',
|
||||
'com.googlecode.libphonenumber',
|
||||
'com.ibm.icu',
|
||||
'com.jakewharton.android.repackaged',
|
||||
'com.jakewharton.timber',
|
||||
'com.kgurgul.flipper',
|
||||
'com.linkedin.dexmaker',
|
||||
'com.mapbox.mapboxsdk',
|
||||
'com.nulab-inc',
|
||||
'com.otaliastudios.opengl',
|
||||
'com.parse.bolts',
|
||||
'com.pinterest',
|
||||
'com.pinterest.ktlint',
|
||||
'com.posthog.android',
|
||||
'com.squareup',
|
||||
'com.squareup.curtains',
|
||||
'com.squareup.duktape',
|
||||
'com.squareup.leakcanary',
|
||||
'com.squareup.moshi',
|
||||
'com.squareup.okhttp3',
|
||||
'com.squareup.okio',
|
||||
'com.squareup.retrofit2',
|
||||
'com.sun.activation',
|
||||
'com.sun.istack',
|
||||
'com.sun.xml.bind',
|
||||
'com.sun.xml.bind.mvn',
|
||||
'com.sun.xml.fastinfoset',
|
||||
'com.thoughtworks.qdox',
|
||||
'com.vanniktech',
|
||||
'commons-cli',
|
||||
'commons-codec',
|
||||
'commons-io',
|
||||
'commons-logging',
|
||||
'info.picocli',
|
||||
'io.arrow-kt',
|
||||
'io.element.android',
|
||||
'io.github.davidburstrom.contester',
|
||||
'io.github.detekt.sarif4k',
|
||||
'io.github.microutils',
|
||||
'io.github.reactivecircus.flowbinding',
|
||||
'io.gitlab.arturbosch.detekt',
|
||||
'io.grpc',
|
||||
'io.jsonwebtoken',
|
||||
'io.kindedj',
|
||||
'io.mockk',
|
||||
'io.netty',
|
||||
'io.noties.markwon',
|
||||
'io.opencensus',
|
||||
'io.reactivex.rxjava2',
|
||||
'io.realm',
|
||||
'it.unimi.dsi',
|
||||
'jakarta.activation',
|
||||
'jakarta.xml.bind',
|
||||
'javax.annotation',
|
||||
'javax.inject',
|
||||
'jline',
|
||||
'jp.wasabeef',
|
||||
'junit',
|
||||
'me.saket',
|
||||
'net.bytebuddy',
|
||||
'net.java',
|
||||
'net.java.dev.jna',
|
||||
'net.lachlanmckee',
|
||||
'net.ltgt.gradle.incap',
|
||||
'net.sf.jopt-simple',
|
||||
'net.sf.kxml',
|
||||
'nl.dionsegijn',
|
||||
'org.amshove.kluent',
|
||||
'org.apache',
|
||||
'org.apache.ant',
|
||||
'org.apache.commons',
|
||||
'org.apache.httpcomponents',
|
||||
'org.apache.sanselan',
|
||||
'org.bouncycastle',
|
||||
'org.checkerframework',
|
||||
'org.codehaus',
|
||||
'org.codehaus.groovy',
|
||||
'org.codehaus.mojo',
|
||||
'org.codehaus.woodstox',
|
||||
'org.eclipse.ee4j',
|
||||
'org.ec4j.core',
|
||||
'org.freemarker',
|
||||
'org.glassfish.jaxb',
|
||||
'org.hamcrest',
|
||||
'org.jacoco',
|
||||
'org.java-websocket',
|
||||
'org.jetbrains',
|
||||
'org.jetbrains.dokka',
|
||||
'org.jetbrains.intellij.deps',
|
||||
'org.jetbrains.kotlin',
|
||||
'org.jetbrains.kotlinx',
|
||||
'org.json',
|
||||
'org.jsoup',
|
||||
'org.junit',
|
||||
'org.junit.jupiter',
|
||||
'org.junit.platform',
|
||||
'org.jvnet.staxex',
|
||||
'org.maplibre.gl',
|
||||
'org.matrix.android',
|
||||
'org.mockito',
|
||||
'org.mongodb',
|
||||
'org.objenesis',
|
||||
'org.opentest4j',
|
||||
'org.ow2',
|
||||
'org.ow2.asm',
|
||||
'org.ow2.asm',
|
||||
'org.reactivestreams',
|
||||
'org.robolectric',
|
||||
'org.slf4j',
|
||||
'org.sonatype.oss',
|
||||
'org.testng',
|
||||
'org.threeten',
|
||||
'org.webjars',
|
||||
'org.yaml',
|
||||
'ru.noties',
|
||||
'xerces',
|
||||
'xml-apis',
|
||||
]
|
||||
],
|
||||
jcenter : [
|
||||
regex: [
|
||||
],
|
||||
group: [
|
||||
'com.amulyakhare',
|
||||
'com.otaliastudios',
|
||||
'com.yqritc',
|
||||
// https://github.com/cmelchior/realmfieldnameshelper/issues/42
|
||||
'dk.ilios',
|
||||
'im.dlg',
|
||||
'me.dm7.barcodescanner',
|
||||
'me.gujun.android',
|
||||
]
|
||||
]
|
||||
]
|
8
diff-match-patch/build.gradle
Normal file
8
diff-match-patch/build.gradle
Normal file
@@ -0,0 +1,8 @@
|
||||
apply plugin: 'java-library'
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
}
|
||||
|
||||
sourceCompatibility = "8"
|
||||
targetCompatibility = "8"
|
@@ -21,15 +21,7 @@ package name.fraser.neil.plaintext;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
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.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
@@ -1,314 +0,0 @@
|
||||
# Adding and removing ThreePids to an account
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Add email](#add-email)
|
||||
* [User enter the email](#user-enter-the-email)
|
||||
* [The email is already added to an account](#the-email-is-already-added-to-an-account)
|
||||
* [The email is free](#the-email-is-free)
|
||||
* [User receives an e-mail](#user-receives-an-e-mail)
|
||||
* [User clicks on the link](#user-clicks-on-the-link)
|
||||
* [User returns on Element](#user-returns-on-element)
|
||||
* [User enters his password](#user-enters-his-password)
|
||||
* [The link has not been clicked](#the-link-has-not-been-clicked)
|
||||
* [Wrong password](#wrong-password)
|
||||
* [The link has been clicked and the account password is correct](#the-link-has-been-clicked-and-the-account-password-is-correct)
|
||||
* [Remove email](#remove-email)
|
||||
* [User want to remove an email from his account](#user-want-to-remove-an-email-from-his-account)
|
||||
* [Email was not bound to an identity server](#email-was-not-bound-to-an-identity-server)
|
||||
* [Email was bound to an identity server](#email-was-bound-to-an-identity-server)
|
||||
* [Add phone number](#add-phone-number)
|
||||
* [The phone number is already added to an account](#the-phone-number-is-already-added-to-an-account)
|
||||
* [The phone number is free](#the-phone-number-is-free)
|
||||
* [User receive a text message](#user-receive-a-text-message)
|
||||
* [User enter the code to the app](#user-enter-the-code-to-the-app)
|
||||
* [Wrong code](#wrong-code)
|
||||
* [Correct code](#correct-code)
|
||||
* [Remove phone number](#remove-phone-number)
|
||||
* [User wants to remove a phone number from his account](#user-wants-to-remove-a-phone-number-from-his-account)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
## Add email
|
||||
|
||||
### User enter the email
|
||||
|
||||
> POST https://homeserver.org/_matrix/client/r0/account/3pid/email/requestToken
|
||||
|
||||
```json
|
||||
{
|
||||
"email": "alice@email-provider.org",
|
||||
"client_secret": "TixzvOnw7nLEUdiQEmkHzkXKrY4HhiGh",
|
||||
"send_attempt": 1
|
||||
}
|
||||
```
|
||||
|
||||
#### The email is already added to an account
|
||||
|
||||
400
|
||||
|
||||
```json
|
||||
{
|
||||
"errcode": "M_THREEPID_IN_USE",
|
||||
"error": "Email is already in use"
|
||||
}
|
||||
```
|
||||
|
||||
#### The email is free
|
||||
|
||||
Wording: "We've sent you an email to verify your address. Please follow the instructions there and then click the button below."
|
||||
|
||||
200
|
||||
|
||||
```json
|
||||
{
|
||||
"sid": "bxyDHuJKsdkjMlTJ"
|
||||
}
|
||||
```
|
||||
|
||||
## User receives an e-mail
|
||||
|
||||
> `homeserver.org` Validate your email
|
||||
>
|
||||
> A request to add an email address to your Matrix account has been received. If this was you, please click the link below to confirm adding this email:
|
||||
https://homeserver.org/_matrix/client/unstable/add_threepid/email/submit_token?token=WUnEhQAmJrXupdEbXgdWvnVIKaGYZFsU&client_secret=TixzvOnw7nLEUdiQEmkHzkXKrY4HhiGh&sid=bxyDHuJKsdkjMlTJ
|
||||
>
|
||||
> If this was not you, you can safely ignore this email. Thank you.
|
||||
|
||||
### User clicks on the link
|
||||
|
||||
The browser displays the following message:
|
||||
|
||||
> Your email has now been validated, please return to your client. You may now close this window.
|
||||
|
||||
### User returns on Element
|
||||
|
||||
User clicks on CONTINUE
|
||||
|
||||
> POST https://homeserver.org/_matrix/client/r0/account/3pid/add
|
||||
|
||||
```json
|
||||
{
|
||||
"sid": "bxyDHuJKsdkjMlTJ",
|
||||
"client_secret": "TixzvOnw7nLEUdiQEmkHzkXKrY4HhiGh"
|
||||
}
|
||||
```
|
||||
|
||||
401 User Interactive Authentication
|
||||
|
||||
```json
|
||||
{
|
||||
"session": "ppvvnozXCQZFaggUBlHJYPjA",
|
||||
"flows": [
|
||||
{
|
||||
"stages": [
|
||||
"m.login.password"
|
||||
]
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### User enters his password
|
||||
|
||||
POST https://homeserver.org/_matrix/client/r0/account/3pid/add
|
||||
|
||||
```json
|
||||
{
|
||||
"sid": "bxyDHuJKsdkjMlTJ",
|
||||
"client_secret": "TixzvOnw7nLEUdiQEmkHzkXKrY4HhiGh",
|
||||
"auth": {
|
||||
"session": "ppvvnozXCQZFaggUBlHJYPjA",
|
||||
"type": "m.login.password",
|
||||
"user": "@benoitx:matrix.org",
|
||||
"password": "weak_password"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### The link has not been clicked
|
||||
|
||||
400
|
||||
|
||||
```json
|
||||
{
|
||||
"errcode": "M_THREEPID_AUTH_FAILED",
|
||||
"error": "No validated 3pid session found"
|
||||
}
|
||||
```
|
||||
|
||||
#### Wrong password
|
||||
|
||||
401
|
||||
|
||||
```json
|
||||
{
|
||||
"session": "fXHOvoQsPMhEebVqTnIrzZJN",
|
||||
"flows": [
|
||||
{
|
||||
"stages": [
|
||||
"m.login.password"
|
||||
]
|
||||
}
|
||||
],
|
||||
"params": {
|
||||
},
|
||||
"completed":[
|
||||
],
|
||||
"error": "Invalid password",
|
||||
"errcode": "M_FORBIDDEN"
|
||||
}
|
||||
```
|
||||
|
||||
#### The link has been clicked and the account password is correct
|
||||
|
||||
200
|
||||
|
||||
```json
|
||||
{}
|
||||
```
|
||||
|
||||
## Remove email
|
||||
|
||||
### User want to remove an email from his account
|
||||
|
||||
> POST https://homeserver.org/_matrix/client/r0/account/3pid/delete
|
||||
|
||||
```json
|
||||
{
|
||||
"medium": "email",
|
||||
"address": "alice@email-provider.org"
|
||||
}
|
||||
```
|
||||
|
||||
#### Email was not bound to an identity server
|
||||
|
||||
200
|
||||
|
||||
```json
|
||||
{
|
||||
"id_server_unbind_result": "no-support"
|
||||
}
|
||||
```
|
||||
|
||||
#### Email was bound to an identity server
|
||||
|
||||
200
|
||||
|
||||
```json
|
||||
{
|
||||
"id_server_unbind_result": "success"
|
||||
}
|
||||
```
|
||||
|
||||
## Add phone number
|
||||
|
||||
> POST https://homeserver.org/_matrix/client/r0/account/3pid/msisdn/requestToken
|
||||
|
||||
```json
|
||||
{
|
||||
"country": "FR",
|
||||
"phone_number": "611223344",
|
||||
"client_secret": "f1K29wFZBEr4RZYatu7xj8nEbXiVpr7J",
|
||||
"send_attempt": 1
|
||||
}
|
||||
```
|
||||
|
||||
Note that the phone number is sent without `+` and without the country code
|
||||
|
||||
#### The phone number is already added to an account
|
||||
|
||||
400
|
||||
|
||||
```json
|
||||
{
|
||||
"errcode": "M_THREEPID_IN_USE",
|
||||
"error": "MSISDN is already in use"
|
||||
}
|
||||
```
|
||||
|
||||
#### The phone number is free
|
||||
|
||||
Wording: "A text message has been sent to +33611223344. Please enter the verification code it contains."
|
||||
|
||||
200
|
||||
|
||||
```json
|
||||
{
|
||||
"msisdn": "33651547677",
|
||||
"intl_fmt": "+33 6 51 54 76 77",
|
||||
"success": true,
|
||||
"sid": "253299954",
|
||||
"submit_url": "https://homeserver.org/_matrix/client/unstable/add_threepid/msisdn/submit_token"
|
||||
}
|
||||
```
|
||||
|
||||
## User receive a text message
|
||||
|
||||
> Riot
|
||||
|
||||
> Your Riot validation code is 892541, please enter this into the app
|
||||
|
||||
### User enter the code to the app
|
||||
|
||||
#### Wrong code
|
||||
|
||||
> POST https://homeserver.org/_matrix/client/unstable/add_threepid/msisdn/submit_token
|
||||
|
||||
```json
|
||||
{
|
||||
"sid": "253299954",
|
||||
"client_secret": "f1K29wFZBEr4RZYatu7xj8nEbXiVpr7J",
|
||||
"token": "111111"
|
||||
}
|
||||
```
|
||||
|
||||
400
|
||||
|
||||
```json
|
||||
{
|
||||
"errcode": "M_UNKNOWN",
|
||||
"error": "Error contacting the identity server"
|
||||
}
|
||||
```
|
||||
|
||||
This is not an ideal, but the client will display a hint to check the entered code to the user.
|
||||
|
||||
#### Correct code
|
||||
|
||||
> POST https://homeserver.org/_matrix/client/unstable/add_threepid/msisdn/submit_token
|
||||
|
||||
```json
|
||||
{
|
||||
"sid": "253299954",
|
||||
"client_secret": "f1K29wFZBEr4RZYatu7xj8nEbXiVpr7J",
|
||||
"token": "892541"
|
||||
}
|
||||
```
|
||||
|
||||
200
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
Then the app call `https://homeserver.org/_matrix/client/r0/account/3pid/add` as per adding an email and follow the same UIS flow
|
||||
|
||||
## Remove phone number
|
||||
|
||||
### User wants to remove a phone number from his account
|
||||
|
||||
This is the same request and response than to remove email, but with this body:
|
||||
|
||||
```json
|
||||
{
|
||||
"medium": "msisdn",
|
||||
"address": "33611223344"
|
||||
}
|
||||
```
|
||||
|
||||
Note that the phone number is provided without `+`, but with the country code.
|
@@ -1,24 +0,0 @@
|
||||
# Analytics in Element
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Solution](#solution)
|
||||
* [How to add a new Event](#how-to-add-a-new-event)
|
||||
* [Forks of Element](#forks-of-element)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
## Solution
|
||||
|
||||
Element is using PostHog to send analytics event.
|
||||
We ask for the user to give consent before sending any analytics data.
|
||||
|
||||
## How to add a new Event
|
||||
|
||||
The analytics plan is shared between all Element clients. To add an Event, please open a PR to this project: https://github.com/matrix-org/matrix-analytics-events
|
||||
|
||||
Then, once the PR has been merged, you can run the tool `import_analytic_plan.sh` to import the plan to Element, and then you can use the new Event. Note that this tool is run by Github action once a week.
|
||||
|
||||
## Forks of Element
|
||||
|
||||
Analytics on forks are disabled by default. Please refer to AnalyticsConfig and there implementation to setup analytics on your project.
|
@@ -1,94 +0,0 @@
|
||||
# Color migration
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Changes](#changes)
|
||||
* [Main change for developers](#main-change-for-developers)
|
||||
* [Remaining work](#remaining-work)
|
||||
* [Migration guide](#migration-guide)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
### Changes
|
||||
|
||||
- use colors defined in https://www.figma.com/file/X4XTH9iS2KGJ2wFKDqkyed/Compound?node-id=557%3A0
|
||||
- remove unused resources and code (ex: PercentView)
|
||||
- split some resource files into smaller file
|
||||
- rework the theme files
|
||||
- ensure material theme is used everywhere in the theme and in the layout
|
||||
- add default style for some views in the theme (ex: Toolbar, etc.)
|
||||
- add some debug screen in the debug menu, to test the themes and the button style
|
||||
- rework the button style to use `materialThemeOverlay` attribute
|
||||
- custom tint icon for menu management has been removed
|
||||
- comment with `riotx` has been updated
|
||||
|
||||
### Main change for developers
|
||||
|
||||
- Read migration guide: https://github.com/vector-im/element-android/pull/3459/files#diff-f0e52729d5e4f6eccbcf72246807aa34ed19c4ef5625ca669df998cd1022874b
|
||||
- Use MaterialAlertDialogBuilder instead of AlertDialog.Builder
|
||||
- some Epoxy Item included a divider. This has been removed. Use a `dividerItem` or `bottomSheetDividerItem` Epoxy items to add a divider
|
||||
- RecyclerView.configureWith now take a divider drawable instead of a divider color
|
||||
|
||||
### Remaining work
|
||||
|
||||
- Cleanup some vector drawables and ensure a tint is always used instead of hard coded color.
|
||||
|
||||
### Migration guide
|
||||
|
||||
Some colors and color attribute has been removed, here is the list and what has to be used now.
|
||||
|
||||
It can help Element Android forks maintainers to migrate their code.
|
||||
|
||||
- riotx_text_primary -> ?vctr_content_primary
|
||||
- riotx_text_secondary -> ?vctr_content_secondary
|
||||
- riotx_text_tertiary -> ?vctr_content_tertiary
|
||||
|
||||
- ?riotx_background -> ?android:colorBackground
|
||||
- riotx_background_light -> element_background_light
|
||||
- riotx_background_dark -> element_background_dark
|
||||
- riotx_background_black -> element_background_black
|
||||
|
||||
- riotx_accent -> ?colorPrimary
|
||||
- riotx_positive_accent -> ?colorPrimary
|
||||
- riotx_accent_alpha25 -> color_primary_alpha25
|
||||
- riotx_notice -> ?colorError
|
||||
- riotx_destructive_accent -> ?colorError
|
||||
- vector_error_color -> ?colorError
|
||||
- vector_warning_color -> ?colorError
|
||||
|
||||
- riotx_bottom_sheet_background -> ?colorSurface
|
||||
- riotx_alerter_background -> ?colorSurface
|
||||
|
||||
- riotx_username_1 -> element_name_01
|
||||
- riotx_username_2 -> element_name_02
|
||||
- riotx_username_3 -> element_name_03
|
||||
- riotx_username_4 -> element_name_04
|
||||
- riotx_username_5 -> element_name_05
|
||||
- riotx_username_6 -> element_name_06
|
||||
- riotx_username_7 -> element_name_07
|
||||
- riotx_username_8 -> element_name_08
|
||||
|
||||
- riotx_avatar_fill_1 -> element_room_01
|
||||
- riotx_avatar_fill_2 -> element_room_02
|
||||
- riotx_avatar_fill_3 -> element_room_03
|
||||
|
||||
- white -> @android:color/white
|
||||
- black -> @android:color/black or emoji_color
|
||||
|
||||
- riotx_list_header_background_color -> ?vctr_header_background
|
||||
- riotx_header_panel_background -> ?vctr_header_background
|
||||
- riotx_list_bottom_sheet_divider_color -> ?vctr_list_separator_on_surface
|
||||
- riotx_list_divider_color -> ?vctr_list_separator
|
||||
- list_divider_color -> ?vctr_list_separator
|
||||
- riotx_header_panel_border_mobile -> ?vctr_list_separator
|
||||
- riotx_bottom_nav_background_border_color -> ?vctr_list_separator
|
||||
- riotx_header_panel_text_secondary -> ?vctr_content_primary
|
||||
|
||||
- link_color_light -> element_link_light
|
||||
- link_color_dark -> element_link_dark
|
||||
|
||||
- riotx_toolbar_primary_text_color -> vctr_content_primary
|
||||
- riotx_toolbar_secondary_text_color -> vctr_content_primary
|
||||
- riot_primary_text_color -> vctr_content_primary
|
||||
|
||||
- riotx_android_secondary -> vctr_content_secondary
|
105
docs/danger.md
105
docs/danger.md
@@ -1,105 +0,0 @@
|
||||
## Danger
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [What does danger checks](#what-does-danger-checks)
|
||||
* [PR check](#pr-check)
|
||||
* [Quality check](#quality-check)
|
||||
* [Setup](#setup)
|
||||
* [Run danger locally](#run-danger-locally)
|
||||
* [Danger user](#danger-user)
|
||||
* [Useful links](#useful-links)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
## What does danger checks
|
||||
|
||||
### PR check
|
||||
|
||||
See the [dangerfile](../tools/danger/dangerfile.js). If you add rules in the dangerfile, please update the list below!
|
||||
|
||||
Here are the checks that Danger does so far:
|
||||
|
||||
- PR description is not empty
|
||||
- Big PR got a warning to recommend to split
|
||||
- PR contains a file for towncrier and extension is checked
|
||||
- PR does not modify frozen classes
|
||||
- PR contains a Sign-Off, with exception for Element employee contributors
|
||||
- PR with change on layout should include screenshot in the description
|
||||
- PR which adds png file warn about the usage of vector drawables
|
||||
- non draft PR should have a reviewer
|
||||
|
||||
### Quality check
|
||||
|
||||
After all the checks that generate checkstyle XML report, such as Ktlint, lint, or Detekt, Danger is run with this [dangerfile](../tools/danger/dangerfile-lint.js), in order to post comments to the PR with the detected error and warnings.
|
||||
|
||||
To run locally, you will have to install the plugin `danger-plugin-lint-report` using:
|
||||
|
||||
```shell
|
||||
yarn add danger-plugin-lint-report --dev
|
||||
```
|
||||
|
||||
## Setup
|
||||
|
||||
This operation should not be necessary, since Danger is already setup for the project.
|
||||
|
||||
To setup danger to the project, run:
|
||||
|
||||
```shell
|
||||
bundle exec danger init
|
||||
```
|
||||
|
||||
## Run danger locally
|
||||
|
||||
When modifying the [dangerfile](../tools/danger/dangerfile.js), you can check it by running Danger locally.
|
||||
|
||||
To run danger locally, install it and run:
|
||||
|
||||
```shell
|
||||
bundle exec danger pr <PR_URL> --dangerfile=./tools/danger/dangerfile.js
|
||||
```
|
||||
|
||||
For instance:
|
||||
|
||||
```shell
|
||||
bundle exec danger pr https://github.com/vector-im/element-android/pull/6637 --dangerfile=./tools/danger/dangerfile.js
|
||||
```
|
||||
|
||||
We may need to create a GitHub token to have less API rate limiting, and then set the env var:
|
||||
|
||||
```shell
|
||||
export DANGER_GITHUB_API_TOKEN='YOUR_TOKEN'
|
||||
```
|
||||
|
||||
Swift and Kotlin (just in case)
|
||||
|
||||
```shell
|
||||
bundle exec danger-swift pr <PR_URL> --dangerfile=./tools/danger/dangerfile.js
|
||||
bundle exec danger-kotlin pr <PR_URL> --dangerfile=./tools/danger/dangerfile.js
|
||||
```
|
||||
|
||||
## Danger user
|
||||
|
||||
To let Danger check all the PRs, including PRs form forks, a GitHub account have been created:
|
||||
- login: ElementBot
|
||||
- password: Stored on Passbolt
|
||||
- GitHub token: A token with limited access has been created and added to the repository https://github.com/vector-im/element-android as secret DANGER_GITHUB_API_TOKEN. This token is not saved anywhere else. In case of problem, just delete it and create a new one, then update the secret.
|
||||
|
||||
PRs from forks do not always have access to the secret `secrets.DANGER_GITHUB_API_TOKEN`, so `secrets.GITHUB_TOKEN` is also provided to the job environment. If `secrets.DANGER_GITHUB_API_TOKEN` is available, it will be used, so user `ElementBot` will comment the PR. Else `secrets.GITHUB_TOKEN` will be used, and bot `github-actions` will comment the PR.
|
||||
|
||||
## Useful links
|
||||
|
||||
- https://danger.systems/
|
||||
- https://danger.systems/js/
|
||||
- https://danger.systems/js/guides/getting_started.html
|
||||
- https://danger.systems/js/reference.html
|
||||
- https://github.com/danger/awesome-danger
|
||||
|
||||
Some danger files to get inspired from
|
||||
|
||||
- https://github.com/artsy/emission/blob/master/dangerfile.ts
|
||||
- https://github.com/facebook/react-native/blob/master/bots/dangerfile.js
|
||||
- https://github.com/apollographql/apollo-client/blob/master/config/dangerfile.ts
|
||||
- https://github.com/styleguidist/react-styleguidist/blob/master/dangerfile.js
|
||||
- https://github.com/storybooks/storybook/blob/master/dangerfile.js
|
||||
- https://github.com/ReactiveX/rxjs/blob/master/dangerfile.js
|
141
docs/design.md
141
docs/design.md
@@ -1,141 +0,0 @@
|
||||
# Element Android design
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [How to import from Figma to the Element Android project](#how-to-import-from-figma-to-the-element-android-project)
|
||||
* [Colors](#colors)
|
||||
* [Text](#text)
|
||||
* [Dimension, position and margin](#dimension-position-and-margin)
|
||||
* [Icons](#icons)
|
||||
* [Export drawable from Figma](#export-drawable-from-figma)
|
||||
* [Import in Android Studio](#import-in-android-studio)
|
||||
* [Images](#images)
|
||||
* [Figma links](#figma-links)
|
||||
* [Coumpound](#coumpound)
|
||||
* [Login](#login)
|
||||
* [Login v2](#login-v2)
|
||||
* [Room list](#room-list)
|
||||
* [Timeline](#timeline)
|
||||
* [Voice message](#voice-message)
|
||||
* [Room settings](#room-settings)
|
||||
* [VoIP](#voip)
|
||||
* [Presence](#presence)
|
||||
* [Spaces](#spaces)
|
||||
* [List to be continued...](#list-to-be-continued)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
## Introduction
|
||||
|
||||
Design at element.io is done using Figma - https://www.figma.com
|
||||
|
||||
## How to import from Figma to the Element Android project
|
||||
|
||||
Integration should be done using the Android development best practice, and should follow the existing convention in the code.
|
||||
|
||||
### Colors
|
||||
|
||||
Element Android already contains all the colors which can be used by the designer, in the module `ui-style`.
|
||||
Some of them depend on the theme, so ensure to use theme attributes and not colors directly.
|
||||
|
||||
### Text
|
||||
|
||||
- click on a text on Figma
|
||||
- on the right panel, information about the style and colors are displayed
|
||||
- in Element Android, text style are already defined, generally you should not create new style
|
||||
- apply the style and the color to the layout
|
||||
|
||||
### Dimension, position and margin
|
||||
|
||||
- click on an item on Figma
|
||||
- dimensions of the item will be displayed.
|
||||
- move the mouse to other items to get relative positioning, margin, etc.
|
||||
|
||||
### Icons
|
||||
|
||||
#### Export drawable from Figma
|
||||
|
||||
- click on the element to export
|
||||
- ensure that the correct layer is selected. Sometimes the parent layer has to be selected on the left panel
|
||||
- on the right panel, click on "export"
|
||||
- select SVG
|
||||
- you can check the preview of what will be exported
|
||||
- click on "export" and save the file locally
|
||||
- unzip the file if necessary
|
||||
|
||||
It's also possible for any icon to go to the main component by right-clicking on the icon.
|
||||
|
||||
#### Import in Android Studio
|
||||
|
||||
- right click on the drawable folder where the drawable will be created
|
||||
- click on "New"/"Vector Asset"
|
||||
- select the exported file
|
||||
- update the filename if necessary
|
||||
- click on "Next" and click on "Finish"
|
||||
- open the created vector drawable
|
||||
- optionally update the color(s) to "#FF0000" (red) to ensure that the drawable is correctly tinted at runtime.
|
||||
|
||||
### Images
|
||||
|
||||
Android 4.3 (18+) fully supports the WebP image format which can often provide smaller image sizes without drastically impacting image quality (depending on the output encoding quality).
|
||||
When importing non vector images, WebP is the preferred format.
|
||||
|
||||
Images can be converted to the WebP within Android Studio by
|
||||
- right clicking the image file within the project file explorer
|
||||
- select `Convert to WebP`
|
||||
|
||||
https://developer.android.com/studio/write/convert-webp
|
||||
|
||||
## Figma links
|
||||
|
||||
Figma links can be included in the layout, for future reference, but it is also OK to add a paragraph below here, to centralize the information
|
||||
|
||||
Main entry point: https://www.figma.com/files/project/5612863/Element?fuid=779371459522484071
|
||||
|
||||
Note: all the Figma links are not publicly available.
|
||||
|
||||
### Coumpound
|
||||
|
||||
Coumpound contains the theme of the application, with all the components, in Light and Dark theme: palette (colors), typography, iconography, etc.
|
||||
|
||||
https://www.figma.com/file/X4XTH9iS2KGJ2wFKDqkyed/Compound
|
||||
|
||||
### Login
|
||||
|
||||
TBD
|
||||
|
||||
#### Login v2
|
||||
|
||||
https://www.figma.com/file/xdV4PuI3DlzA1EiBvbrggz/Login-Flow-v2
|
||||
|
||||
### Room list
|
||||
|
||||
TBD
|
||||
|
||||
### Timeline
|
||||
|
||||
https://www.figma.com/file/x1HYYLYMmbYnhfoz2c2nGD/%5BRiotX%5D-Misc?node-id=0%3A1
|
||||
|
||||
### Voice message
|
||||
|
||||
https://www.figma.com/file/uaWc62Ux2DkZC4OGtAGcNc/Voice-Messages?node-id=473%3A12
|
||||
|
||||
### Room settings
|
||||
|
||||
TBD
|
||||
|
||||
### VoIP
|
||||
|
||||
https://www.figma.com/file/V6m2z0oAtUV1l8MdyIrAep/VoIP?node-id=4254%3A25767
|
||||
|
||||
### Presence
|
||||
|
||||
https://www.figma.com/file/qmvEskET5JWva8jZJ4jX8o/Presence---User-Status?node-id=114%3A9174
|
||||
(Option B is chosen)
|
||||
|
||||
### Spaces
|
||||
|
||||
https://www.figma.com/file/m7L63aGPW7iHnIYStfdxCe/Spaces?node-id=192%3A30161
|
||||
|
||||
### List to be continued...
|
@@ -1,58 +0,0 @@
|
||||
# Flipper
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Setup](#setup)
|
||||
* [Troubleshoot](#troubleshoot)
|
||||
* [No device found issue](#no-device-found-issue)
|
||||
* [Diagnostic Activity](#diagnostic-activity)
|
||||
* [Other](#other)
|
||||
* [Links](#links)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
## Introduction
|
||||
|
||||
[Flipper](https://fbflipper.com) is a powerful tool from Meta, which allow to inspect the running application details and states from your computer.
|
||||
|
||||
Flipper is configured in the Element Android project to let the developers be able to:
|
||||
- inspect all the Realm databases content;
|
||||
- do layout inspection;
|
||||
- see the crash logs;
|
||||
- see the logcat;
|
||||
- see all the network requests;
|
||||
- see all the SharedPreferences;
|
||||
- take screenshots and record videos of the device;
|
||||
- and more!
|
||||
|
||||
## Setup
|
||||
|
||||
- Install Flipper on your computer. Follow instructions here: https://fbflipper.com/docs/getting-started/index/
|
||||
- Run the debug version of Element on an emulator or on a real device.
|
||||
|
||||
### Troubleshoot
|
||||
|
||||
#### No device found issue
|
||||
|
||||
The configuration of the Flipper application has to be updated. The issue has been asked and answered here: https://stackoverflow.com/questions/71744103/android-emulator-unable-to-connect-to-flipper/72608113#72608113
|
||||
|
||||
#### Diagnostic Activity
|
||||
|
||||
Flipper comes with a Diagnostic Activity that you can start from command line using:
|
||||
|
||||
```shell
|
||||
adb shell am start -n im.vector.app.debug/com.facebook.flipper.android.diagnostics.FlipperDiagnosticActivity
|
||||
```
|
||||
|
||||
It provides some log which can help to figure out what's going on client side.
|
||||
|
||||
#### Other
|
||||
|
||||
https://fbflipper.com/docs/getting-started/troubleshooting/android/ may help.
|
||||
|
||||
## Links
|
||||
|
||||
- Official Flipper website: https://fbflipper.com
|
||||
- Realm Plugin for Flipper: https://github.com/kamgurgul/Flipper-Realm
|
||||
- Dedicated Matrix room: https://matrix.to/#/#unifiedpush:matrix.org
|
@@ -1,33 +0,0 @@
|
||||
Useful links:
|
||||
- https://dagger.dev/hilt/migration-guide
|
||||
- https://dagger.dev/hilt/quick-start
|
||||
|
||||
Hilt is built on top of Dagger 2 and simplify usage by removing needs to create components manually.
|
||||
|
||||
When you create a new feature, you should have the following:
|
||||
|
||||
Annotate your Activity with @AndroidEntryPoint
|
||||
Annotate your Fragment with @AndroidEntryPoint
|
||||
If you have a BottomSheetFragment => Annotate it with @AndroidEntryPoint
|
||||
Add your ViewModel.Factory to the MavericksViewModelModule
|
||||
Makes sure your ViewModel as the following code:
|
||||
|
||||
```
|
||||
@AssistedFactory
|
||||
interface Factory: MavericksAssistedViewModelFactory<MyViewModel, MyViewState> {
|
||||
override fun create(initialState: MyViewState): MyViewModel
|
||||
}
|
||||
|
||||
companion object : MavericksViewModelFactory<MyViewModel, MyViewState> by hiltMavericksViewModelFactory()
|
||||
```
|
||||
|
||||
## Some remarks
|
||||
|
||||
@MavericksViewModelScope dependencies can't be injected inside Fragments/Activities
|
||||
You can only inject @Singleton, @MavericksViewModelScope or unscoped dependencies inside Maverick ViewModels
|
||||
You can access some specific dependencies from Singleton component by using
|
||||
```
|
||||
context.singletonEntryPoint()
|
||||
```
|
||||
Be aware that only the app has been migrated to Hilt and not the SDK.
|
||||
|
@@ -1,106 +0,0 @@
|
||||
# Identity server
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Implementation](#implementation)
|
||||
* [Related MSCs](#related-mscs)
|
||||
* [Steps and requirements](#steps-and-requirements)
|
||||
* [Screens](#screens)
|
||||
* [Settings](#settings)
|
||||
* [Discovery screen](#discovery-screen)
|
||||
* [Set identity server screen](#set-identity-server-screen)
|
||||
* [Ref:](#ref:)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
Issue: #607
|
||||
PR: #1354
|
||||
|
||||
## Introduction
|
||||
Identity servers support contact discovery on Matrix by letting people look up Third Party Identifiers to see if the owner has publicly linked them with their Matrix ID.
|
||||
|
||||
## Implementation
|
||||
|
||||
The current implementation was Inspired by the code from Riot-Android.
|
||||
|
||||
Difference though (list not exhaustive):
|
||||
- Only API v2 is supported (see https://matrix.org/docs/spec/identity_service/latest)
|
||||
- Homeserver has to be up to date to support binding (Versions.isLoginAndRegistrationSupportedBySdk() has to return true)
|
||||
- The SDK managed the session and client secret when binding ThreePid. Those data are not exposed to the client.
|
||||
- The SDK supports incremental sendAttempt (this is not used by Element)
|
||||
- The "Continue" button is now under the information, and not as the same place that the checkbox
|
||||
- The app can cancel a binding. Current data are erased from DB.
|
||||
- The API (IdentityService) is improved.
|
||||
- A new DB to store data related to the identity server management.
|
||||
|
||||
Missing features (list not exhaustive):
|
||||
- Invite by 3Pid (will be in a dedicated PR)
|
||||
- Add email or phone to account (not P1, can be done on Element-Web)
|
||||
- List email and phone of the account (could be done in a dedicated PR)
|
||||
- Search contact (not P1)
|
||||
- Logout from identity server when user sign out or deactivate his account.
|
||||
|
||||
## Related MSCs
|
||||
The list can be found here: https://matrix.org/blog/2019/09/27/privacy-improvements-in-synapse-1-4-and-riot-1-4
|
||||
|
||||
## Steps and requirements
|
||||
|
||||
- Only one identity server by account can be set. The user's choice is stored in account data with key `m.identity_server`. But every clients will managed its own token to log in to the identity server
|
||||
```json
|
||||
{
|
||||
"type": "m.identity_server",
|
||||
"content": {
|
||||
"base_url": "https://matrix.org"
|
||||
}
|
||||
}
|
||||
```
|
||||
- The accepted terms are stored in the account data:
|
||||
```json
|
||||
{
|
||||
"type": "m.accepted_terms",
|
||||
"content": {
|
||||
"accepted": [
|
||||
"https://vector.im/identity-server-privacy-notice-1"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- Default identity server URL, from Wellknown data is proposed to the user.
|
||||
- Identity server can be set
|
||||
- Identity server can be changed on another user's device, so when the change is detected (thanks to account data sync) Element should properly disconnect from a previous identity server (I think it was not the case in Riot-Android, where we keep the token forever)
|
||||
- Registration to the identity server is managed with an openId token
|
||||
- Terms of service can be accepted when configuring the identity server.
|
||||
- Terms of service can be accepted after, if they change.
|
||||
- Identity server can be modified
|
||||
- Identity server can be disconnected with a warning dialog, with special content if there are current bound 3pid on this identity server.
|
||||
- Email can be bound
|
||||
- Email can be unbound
|
||||
- Phone can be bound
|
||||
- Phone can be unbound
|
||||
- Look up can be performed, to get matrixIds from local contact book (phone and email): Android permission correctly handled (not done yet)
|
||||
- Look up pepper can be updated if it is rotated on the identity server
|
||||
- Invitation using 3PID can be done (See #548) (not done yet)
|
||||
- Homeserver access-token will never be sent to an identity server
|
||||
- When user sign-out: logout from the identity server if any.
|
||||
- When user deactivate account: logout from the identity server if any.
|
||||
|
||||
## Screens
|
||||
|
||||
### Settings
|
||||
|
||||
Identity server settings can be accessed from the internal setting of the application, both from "Discovery" section and from identity detail section.
|
||||
|
||||
### Discovery screen
|
||||
|
||||
This screen displays the identity server configuration and the binding of the user's ThreePid (email and msisdn). This is the main screen of the feature.
|
||||
|
||||
### Set identity server screen
|
||||
|
||||
This screen is a form to set a new identity server URL
|
||||
|
||||
## Ref:
|
||||
- https://matrix.org/blog/2019/09/27/privacy-improvements-in-synapse-1-4-and-riot-1-4 is a good summary of the role of an identity server and the proper way to configure and use it in respect to the privacy and the consent of the user.
|
||||
- API documentation: https://matrix.org/docs/spec/identity_service/latest
|
||||
- vector.im TOS: https://vector.im/identity-server-privacy-notice
|
@@ -1,18 +1,5 @@
|
||||
# Integration tests
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Pre requirements](#pre-requirements)
|
||||
* [Install and run Synapse](#install-and-run-synapse)
|
||||
* [Run the test](#run-the-test)
|
||||
* [Stop Synapse](#stop-synapse)
|
||||
* [Troubleshoot](#troubleshoot)
|
||||
* [Android Emulator does cannot reach the homeserver](#android-emulator-does-cannot-reach-the-homeserver)
|
||||
* [Tests partially run but some fail with "Unable to contact localhost:8080"](#tests-partially-run-but-some-fail-with-"unable-to-contact-localhost:8080")
|
||||
* [virtualenv command fails](#virtualenv-command-fails)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
Integration tests are useful to ensure that the code works well for any use cases.
|
||||
|
||||
They can also be used as sample on how to use the Matrix SDK.
|
||||
@@ -56,17 +43,14 @@ virtualenv -p python3 env
|
||||
source env/bin/activate
|
||||
pip install -e .
|
||||
demo/start.sh --no-rate-limit
|
||||
|
||||
```
|
||||
|
||||
Alternatively, to install the latest Synapse release package (and not a cloned branch) you can run the following instead of `git clone` and `pip install -e .`:
|
||||
Alternatively, to install the latest Synapse release package (and not a cloned branch) you can run the following instead of `pip install -e .`:
|
||||
|
||||
```bash
|
||||
pip install matrix-synapse
|
||||
```
|
||||
|
||||
On your first run, you will want to stop the demo and edit the config to correct the `public_baseurl` to http://10.0.2.2:8080 and restart the server.
|
||||
|
||||
You should now have 3 running federated Synapse instances 🎉, at http://127.0.0.1:8080/, http://127.0.0.1:8081/ and http://127.0.0.1:8082/, which should display a "It Works! Synapse is running" message.
|
||||
|
||||
## Run the test
|
||||
@@ -75,12 +59,6 @@ It's recommended to run tests using an Android Emulator and not a real device. F
|
||||
|
||||
You can run all the tests in the `androidTest` folders.
|
||||
|
||||
It can be done using this command:
|
||||
|
||||
```bash
|
||||
./gradlew vector:connectedAndroidTest matrix-sdk-android:connectedAndroidTest
|
||||
```
|
||||
|
||||
## Stop Synapse
|
||||
|
||||
To stop Synapse, you can run the following commands:
|
||||
@@ -103,18 +81,6 @@ You'll need python3 to be able to run synapse
|
||||
|
||||
Try on the Emulator browser to open "http://10.0.2.2:8080". You should see the "Synapse is running" message.
|
||||
|
||||
### Tests partially run but some fail with "Unable to contact localhost:8080"
|
||||
|
||||
This is because the `public_baseurl` of synapse is not consistent with the endpoint that the tests are connecting to.
|
||||
|
||||
Ensure you have the following configuration in `demo/etc/8080.config`.
|
||||
|
||||
```
|
||||
public_baseurl: http://10.0.2.2:8080/
|
||||
```
|
||||
|
||||
After changing this you will need to restart synapse using `demo/stop.sh` and `demo/start.sh` to load the new configuration.
|
||||
|
||||
### virtualenv command fails
|
||||
|
||||
You can try using
|
||||
|
@@ -1,96 +0,0 @@
|
||||
# Jitsi in Element Android
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Native Jitsi SDK](#native-jitsi-sdk)
|
||||
* [How to build the Jitsi Meet SDK](#how-to-build-the-jitsi-meet-sdk)
|
||||
* [Jitsi version](#jitsi-version)
|
||||
* [Run the build script](#run-the-build-script)
|
||||
* [Link with the new generated library](#link-with-the-new-generated-library)
|
||||
* [Sanity tests](#sanity-tests)
|
||||
* [Export the build library](#export-the-build-library)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
Native Jitsi support has been added to Element Android by the PR [#1914](https://github.com/vector-im/element-android/pull/1914). The description of the PR contains some documentation about the behaviour in each possible room configuration.
|
||||
|
||||
Also, ensure to have a look on [the documentation from Element Web](https://github.com/vector-im/element-web/blob/develop/docs/jitsi.md)
|
||||
|
||||
The official documentation about how to integrate the Jitsi SDK in an Android app is available here: https://jitsi.github.io/handbook/docs/dev-guide/dev-guide-android-sdk.
|
||||
|
||||
## Native Jitsi SDK
|
||||
|
||||
The Jitsi SDK is built by ourselves with the flag LIBRE_BUILD, to be able to be integrated on the F-Droid version of Element Android.
|
||||
|
||||
The generated maven repository is then host in the project https://github.com/vector-im/jitsi_libre_maven
|
||||
|
||||
### How to build the Jitsi Meet SDK
|
||||
|
||||
#### Jitsi version
|
||||
|
||||
Update the script `./tools/jitsi/build_jisti_libs.sh` with the tag of the project `https://github.com/jitsi/jitsi-meet`.
|
||||
|
||||
Latest tag can be found from this page: https://github.com/jitsi/jitsi-meet-release-notes/blob/master/CHANGELOG-MOBILE-SDKS.md
|
||||
|
||||
Currently we are building the version with the tag `android-sdk-3.10.0`.
|
||||
|
||||
#### Run the build script
|
||||
|
||||
At the root of the Element Android, run the following script:
|
||||
|
||||
```shell script
|
||||
./tools/jitsi/build_jisti_libs.sh
|
||||
```
|
||||
|
||||
It will build the Jitsi Meet Android library and put every generated files in the folder `/tmp/jitsi`
|
||||
|
||||
#### Link with the new generated library
|
||||
|
||||
- Update the file `./build.gradle` to use the previously created local Maven repository. Currently we have this line:
|
||||
|
||||
```groovy
|
||||
url "https://github.com/vector-im/jitsi_libre_maven/raw/master/android-sdk-3.10.0"
|
||||
```
|
||||
|
||||
You can uncomment and update the line starting with `// url "file://...` and comment the line starting with `url`, to test the library using the locally generated Maven repository.
|
||||
|
||||
- Update the dependency of the Jitsi Meet library in the file `./vector/build.gradle`. Currently we have this line:
|
||||
|
||||
```groovy
|
||||
implementation('org.jitsi.react:jitsi-meet-sdk:3.10.0')
|
||||
```
|
||||
|
||||
- Update the dependency of the WebRTC library in the file `./vector/build.gradle`. Currently we have this line:
|
||||
|
||||
```groovy
|
||||
implementation('com.facebook.react:react-native-webrtc:1.92.1-jitsi-9093212@aar')
|
||||
```
|
||||
|
||||
- Perform a gradle sync and build the project
|
||||
- Perform test
|
||||
|
||||
#### Sanity tests
|
||||
|
||||
In order to validate that the upgrade of the Jitsi and WebRTC dependency does not break anything, the following sanity tests have to be performed, using two devices:
|
||||
- Make 1-1 audio call (so using WebRTC)
|
||||
- Make 1-1 video call (so using WebRTC)
|
||||
- Create and join a conference call with audio only (so using Jitsi library). Leave the conference. Join it again.
|
||||
- Create and join a conference call with audio and video (so using Jitsi library) Leave the conference. Join it again.
|
||||
|
||||
#### Export the build library
|
||||
|
||||
If all the tests are passed, you can export the generated Jitsi library to our Maven repository.
|
||||
|
||||
- Clone the project https://github.com/vector-im/jitsi_libre_maven.
|
||||
- Create a new folder with the version name.
|
||||
- Copy every generated files form `/tmp/jitsi` to the folder you have just created.
|
||||
- Commit and push the change on https://github.com/vector-im/jitsi_libre_maven.
|
||||
- Update the file `./build.gradle` to use the previously created Maven repository. Currently we have this line:
|
||||
|
||||
```groovy
|
||||
url "https://github.com/vector-im/jitsi_libre_maven/raw/master/android-sdk-3.10.0"
|
||||
```
|
||||
|
||||
- Build the project and perform the sanity tests again.
|
||||
|
||||
- Update the file `/CHANGES.md` to notify about the library upgrade, and create a regular PR for project Element Android.
|
@@ -1,11 +0,0 @@
|
||||
Useful links:
|
||||
- https://airbnb.io/mavericks/#/new-2x
|
||||
|
||||
Mavericks 2 is replacing MvRx, by removing usage of Rx by Flow, both internally and in the API.
|
||||
See the link ^ to have more intel, but basically, the changes are:
|
||||
|
||||
session.rx() => session.flow()
|
||||
room.rx() => room.flow()
|
||||
subscribe { }.disposeOnClear() => onEach { }.launchIn(viewModelScope)
|
||||
|
||||
Only using manually onEach requires to add launchIn,any other methods provided by Mavericks on viewModel and activity/fragment are already taking care of lifecycle.
|
@@ -1,54 +0,0 @@
|
||||
# Nightly builds
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Configuration](#configuration)
|
||||
* [How to register to get nightly build](#how-to-register-to-get-nightly-build)
|
||||
* [Build nightly manually](#build-nightly-manually)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
## Configuration
|
||||
|
||||
The nightly build will contain what's on develop, in release mode, for Gplay variant. It is signed using a dedicated signature, and has a dedicated appId (`im.vector.app.nightly`), so it can be installed along with the production version of Element Android. The only other difference compared to Element Android is a different app icon background. We do not want to change the app name since it will also affect some strings in the app, and we do want to do that.
|
||||
|
||||
Nightly builds are built and released to Firebase every days, and automatically.
|
||||
|
||||
This is recommended to exclusively use this app, with your main account, instead of Element Android, and fallback to Element Android just in case of regression, to discover as soon as possible any regression, and report it to the team. To avoid double notification, you may want to disable the notification from the Element Android production version. Just open Element Android, navigate to `Settings/Notifications` and uncheck `Enable notifications for this session`.
|
||||
|
||||
*Note:* Due to a limitation of Firebase, the nightly build is the universal build, which means that the size of the APK is a bit bigger, but this should not have any other side effect.
|
||||
|
||||
## How to register to get nightly build
|
||||
|
||||
Provide your email to the Android team, who will add it to the list "External testers" on Firebase. You will then receive an invite on the provided email.
|
||||
|
||||
Follow the instructions on the email to install the latest nightly build. This is not clear yet if new nightly build will be automatically installed or not.
|
||||
|
||||
## Build nightly manually
|
||||
|
||||
Nightly build can be built manually from your computer. You will need to retrieved some secrets from Passbolt and add them to your file `~/.gradle/gradle.properties`:
|
||||
|
||||
```
|
||||
signing.element.nightly.storePassword=VALUE_FROM_PASSBOLT
|
||||
signing.element.nightly.keyId=VALUE_FROM_PASSBOLT
|
||||
signing.element.nightly.keyPassword=VALUE_FROM_PASSBOLT
|
||||
```
|
||||
|
||||
You will also need to add the environment variable `FIREBASE_TOKEN`:
|
||||
|
||||
```sh
|
||||
export FIREBASE_TOKEN=VALUE_FROM_PASSBOLT
|
||||
```
|
||||
|
||||
Then you can run the following commands (which are also used in the file for [the GitHub action](../.github/workflows/nightly.yml)):
|
||||
|
||||
```sh
|
||||
git checkout develop
|
||||
mv towncrier.toml towncrier.toml.bak
|
||||
sed 's/CHANGES\.md/CHANGES_NIGHTLY\.md/' towncrier.toml.bak > towncrier.toml
|
||||
rm towncrier.toml.bak
|
||||
yes n | towncrier build --version nightly
|
||||
./gradlew assembleGplayNightly appDistributionUploadGplayNightly $CI_GRADLE_ARG_PROPERTIES
|
||||
```
|
||||
|
||||
Then you can reset the change on the codebase.
|
@@ -1,52 +1,47 @@
|
||||
This document aims to describe how Element android displays notifications to the end user. It also clarifies notifications and background settings in the app.
|
||||
This document aims to describe how RiotX android displays notifications to the end user. It also clarifies notifications and background settings in the app.
|
||||
|
||||
# Table of Contents
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Prerequisites Knowledge](#prerequisites-knowledge)
|
||||
* [How does a matrix client get a message from a homeserver?](#how-does-a-matrix-client-get-a-message-from-a-homeserver?)
|
||||
* [How does a mobile app receives push notification](#how-does-a-mobile-app-receives-push-notification)
|
||||
* [Push VS Notification](#push-vs-notification)
|
||||
* [Push in the matrix federated world](#push-in-the-matrix-federated-world)
|
||||
* [How does the homeserver know when to notify a client?](#how-does-the-homeserver-know-when-to-notify-a-client?)
|
||||
* [Push vs privacy, and mitigation](#push-vs-privacy-and-mitigation)
|
||||
* [Background processing limitations](#background-processing-limitations)
|
||||
* [Element Notification implementations](#element-notification-implementations)
|
||||
* [Requirements](#requirements)
|
||||
* [Foreground sync mode (Gplay and F-Droid)](#foreground-sync-mode-gplay-and-f-droid)
|
||||
* [Push (FCM) received in background](#push-fcm-received-in-background)
|
||||
* [FCM Fallback mode](#fcm-fallback-mode)
|
||||
* [F-Droid background Mode](#f-droid-background-mode)
|
||||
* [Application Settings](#application-settings)
|
||||
|
||||
<!--- END -->
|
||||
1. [Prerequisites Knowledge](#prerequisites-knowledge)
|
||||
* [How does a matrix client gets a message from a Home Server?](#how-does-a-matrix-client-gets-a-message-from-a-home-server)
|
||||
* [How does a mobile app receives push notification?](#how-does-a-mobile-app-receives-push-notification)
|
||||
* [Push VS Notification](#push-vs-notification)
|
||||
* [Push in the matrix federated world](#push-in-the-matrix-federated-world)
|
||||
* [How does the Home Server knows when to notify a client?](#how-does-the-home-server-knows-when-to-notify-a-client)
|
||||
* [Push vs privacy, and mitigation](#push-vs-privacy-and-mitigation)
|
||||
* [Background processing limitations](#background-processing-limitations)
|
||||
2. [RiotX Notification implementations](#riotx-notification-implementations)
|
||||
* [Requirements](#requirements)
|
||||
* [Foreground sync mode (Gplay & F-Droid)](#foreground-sync-mode-gplay-f-droid)
|
||||
* [Push (FCM) received in background](#push-fcm-received-in-background)
|
||||
* [FCM Fallback mode](#fcm-fallback-mode)
|
||||
* [F-Droid background Mode](#f-droid-background-mode)
|
||||
3. [Application Settings](#application-settings)
|
||||
|
||||
|
||||
First let's start with some prerequisite knowledge
|
||||
|
||||
## Prerequisites Knowledge
|
||||
# Prerequisites Knowledge
|
||||
|
||||
### How does a matrix client get a message from a homeserver?
|
||||
## How does a matrix client gets a message from a Home Server?
|
||||
|
||||
In order to get messages from a homeserver, a matrix client need to perform a ``sync`` operation.
|
||||
In order to get messages from a home server, a matrix client need to perform a ``sync`` operation.
|
||||
|
||||
`To read events, the intended flow of operation is for clients to first call the /sync API without a since parameter. This returns the most recent message events for each room, as well as the state of the room at the start of the returned timeline. `
|
||||
|
||||
The client need to call the `sync` API periodically in order to get incremental updates of the server state (new messages).
|
||||
The client need to call the `sync`API periodically in order to get incremental updates of the server state (new messages).
|
||||
This mechanism is known as **HTTP long Polling**.
|
||||
|
||||
Using the **HTTP Long Polling** mechanism a client polls a server requesting new information.
|
||||
Using the **HTTP Long Polling** mechanism a client polls a server requesting new information.
|
||||
The server *holds the request open until new data is available*.
|
||||
Once available, the server responds and sends the new information.
|
||||
When the client receives the new information, it immediately sends another request, and the operation is repeated.
|
||||
This effectively emulates a server push feature.
|
||||
|
||||
The HTTP long Polling can be fine tuned in the **SDK** using two parameters:
|
||||
* timeout (Sync request timeout)
|
||||
* timout (Sync request timeout)
|
||||
* delay (Delay between each sync)
|
||||
|
||||
**timeout** is a server parameter, defined by:
|
||||
**timeout** is a server paramter, defined by:
|
||||
```
|
||||
The maximum time to wait, in milliseconds, before returning this request.`
|
||||
If no events (or other data) become available before this time elapses, the server will return a response with empty fields.
|
||||
@@ -55,9 +50,9 @@ By default, this is 0, so the server will return immediately even if the respons
|
||||
|
||||
**delay** is a client preference. When the server responds to a sync request, the client waits for `delay`before calling a new sync.
|
||||
|
||||
When the Element Android app is open (i.e in foreground state), the default timeout is 30 seconds, and delay is 0.
|
||||
When the RiotX Android app is open (i.e in foreground state), the default timeout is 30 seconds, and delay is 0.
|
||||
|
||||
### How does a mobile app receives push notification
|
||||
## How does a mobile app receives push notification
|
||||
|
||||
Push notification is used as a way to wake up a mobile application when some important information is available and should be processed.
|
||||
|
||||
@@ -71,31 +66,31 @@ FCM will only work on android devices that have Google plays services installed
|
||||
(In simple terms, Google Play Services is a background service that runs on Android, which in turn helps in integrating Google’s advanced functionalities to other applications)
|
||||
|
||||
De-Googlified devices need to rely on something else in order to stay up to date with a server.
|
||||
There some cases when devices with google services cannot use FCM (network infrastructure limitations -firewalls-,
|
||||
privacy and or independence requirement, source code licence)
|
||||
There some cases when devices with google services cannot use FCM (network infrastructure limitations -firewalls- ,
|
||||
privacy and or independency requirement, source code licence)
|
||||
|
||||
### Push VS Notification
|
||||
## Push VS Notification
|
||||
|
||||
This need some disambiguation, because it is the source of common confusion:
|
||||
|
||||
|
||||
*The fact that you see a notification on your screen does not mean that you have successfully configured your PUSH platform.*
|
||||
*The fact that you see a notification on your screen does not mean that you have successfully configured your PUSH plateform.*
|
||||
|
||||
Technically there is a difference between a push and a notification. A notification is what you see on screen and/or in the notification Menu/Drawer (in the top bar of the phone).
|
||||
|
||||
Notifications are not always triggered by a push (One can display a notification locally triggered by an alarm)
|
||||
|
||||
|
||||
### Push in the matrix federated world
|
||||
## Push in the matrix federated world
|
||||
|
||||
In order to send a push to a mobile, App developers need to have a server that will use the FCM APIs, and these APIs requires authentication!
|
||||
This server is called a **Push Gateway** in the matrix world
|
||||
|
||||
That means that Element Android, a matrix client created by New Vector, is using a **Push Gateway** with the needed credentials (FCM API secret Key) in order to send push to the New Vector client.
|
||||
That means that RiotX Android, a matrix client created by New Vector, is using a **Push Gateway** with the needed credentials (FCM API secret Key) in order to send push to the New Vector client.
|
||||
|
||||
If you create your own matrix client, you will also need to deploy an instance of a **Push Gateway** with the credentials needed to use FCM for your app.
|
||||
|
||||
On registration, a matrix client must tell its homeserver what Push Gateway to use.
|
||||
On registration, a matrix client must tell to it's Home Server what Push Gateway to use.
|
||||
|
||||
See [Sygnal](https://github.com/matrix-org/sygnal/) for a reference implementation.
|
||||
```
|
||||
@@ -123,21 +118,21 @@ Client/Server API + | | | | |
|
||||
```
|
||||
|
||||
Recommended reading:
|
||||
* https://thomask.sdf.org/blog/2016/12/11/riots-magical-push-notifications-in-ios.html
|
||||
* https://thomask.sdf.org/blog/2016/12/11/riots-magical-push-notifications-in-ios.html
|
||||
* https://matrix.org/docs/spec/client_server/r0.4.0.html#id128
|
||||
|
||||
|
||||
### How does the homeserver know when to notify a client?
|
||||
## How does the Home Server knows when to notify a client?
|
||||
|
||||
This is defined by [**push rules**](https://matrix.org/docs/spec/client_server/r0.4.0.html#push-rules-).
|
||||
|
||||
`A push rule is a single rule that states under what conditions an event should be passed onto a push gateway and how the notification should be presented (sound / importance).`
|
||||
|
||||
A homeserver can be configured with default rules (for Direct messages, group messages, mentions, etc.. ).
|
||||
A Home Server can be configured with default rules (for Direct messages, group messages, mentions, etc.. ).
|
||||
|
||||
There are different kind of push rules, it can be per room (each new message on this room should be notified), it can also define a pattern that a message should match (when you are mentioned, or key word based).
|
||||
|
||||
Notifications have 2 'levels' (`highlighted = true/false sound = default/custom`). In Element these notifications level are reflected as Noisy/Silent.
|
||||
Notifications have 2 'levels' (`highlighted = true/false sound = default/custom`). In RiotX these notifications level are reflected as Noisy/Silent.
|
||||
|
||||
**What about encrypted messages?**
|
||||
|
||||
@@ -145,14 +140,14 @@ Of course, content patterns matching cannot be used for encrypted messages serve
|
||||
|
||||
That is why clients are able to **process the push rules client side** to decide what kind of notification should be presented for a given event.
|
||||
|
||||
### Push vs privacy, and mitigation
|
||||
## Push vs privacy, and mitigation
|
||||
|
||||
As seen previously, App developers don't directly send a push to the end user's device, they use a Push Provider as intermediary. So technically this intermediary is able to read the content of what is sent.
|
||||
|
||||
App developers usually mitigate this by sending a `silent notification`, that is a notification with no identifiable data, or with an encrypted payload. When the push is received the app can then synchronise to it's server in order to generate a local notification.
|
||||
|
||||
|
||||
### Background processing limitations
|
||||
## Background processing limitations
|
||||
|
||||
A mobile applications process live in a managed word, meaning that its process can be limited (e.g no network access), stopped or killed at almost anytime by the Operating System.
|
||||
|
||||
@@ -163,7 +158,7 @@ In a nutshell, apps can't do much in background now.
|
||||
|
||||
If the devices is not plugged and stays IDLE for a certain amount of time, radio (mobile connectivity) and CPU can/will be turned off.
|
||||
|
||||
For an application like Element, where users can receive important information at anytime, the best option is to rely on a push system (Google's Firebase Message a.k.a FCM). FCM high priority push can wake up the device and whitelist an application to perform background task (for a limited but unspecified amount of time).
|
||||
For an application like RiotX, where users can receive important information at anytime, the best option is to rely on a push system (Google's Firebase Message a.k.a FCM). FCM high priority push can wake up the device and whitelist an application to perform background task (for a limited but unspecified amount of time).
|
||||
|
||||
Notice that this is still evolving, and in future versions application that has been 'background restricted' by users won't be able to wake up even when a high priority push is received. Also high priority notifications could be rate limited (not defined anywhere)
|
||||
|
||||
@@ -172,41 +167,41 @@ The documentation on this subject is vague, and as per our experiments not alway
|
||||
|
||||
It is getting more and more complex to have reliable notifications when FCM is not used.
|
||||
|
||||
## Element Notification implementations
|
||||
# RiotX Notification implementations
|
||||
|
||||
### Requirements
|
||||
## Requirements
|
||||
|
||||
Element Android must work with and without FCM.
|
||||
* The Element android app published on F-Droid do not rely on FCM (all related dependencies are not present)
|
||||
* The Element android app published on google play rely on FCM, with a fallback mode when FCM registration has failed (e.g outdated or missing Google Play Services)
|
||||
RiotX Android must work with and without FCM.
|
||||
* The RiotX android app published on F-Droid do not rely on FCM (all related dependencies are not present)
|
||||
* The RiotX android app published on google play rely on FCM, with a fallback mode when FCM registration has failed (e.g outdated or missing Google Play Services)
|
||||
|
||||
### Foreground sync mode (Gplay and F-Droid)
|
||||
## Foreground sync mode (Gplay & F-Droid)
|
||||
|
||||
When in foreground, Element performs sync continuously with a timeout value set to 10 seconds (see HttpPooling).
|
||||
When in foreground, RiotX performs sync continuously with a timeout value set to 10 seconds (see HttpPooling).
|
||||
|
||||
As this mode does not need to live beyond the scope of the application, and as per Google recommendation, Element uses the internal app resources (Thread and Timers) to perform the syncs.
|
||||
As this mode does not need to live beyond the scope of the application, and as per Google recommendation, RiotX uses the internal app resources (Thread and Timers) to perform the syncs.
|
||||
|
||||
This mode is turned on when the app enters foreground, and off when enters background.
|
||||
|
||||
In background, and depending on whether push is available or not, Element will use different methods to perform the syncs (Workers / Alarms / Service)
|
||||
In background, and depending on wether push is available or not, RiotX will use different methods to perform the syncs (Workers / Alarms / Service)
|
||||
|
||||
### Push (FCM) received in background
|
||||
## Push (FCM) received in background
|
||||
|
||||
In order to enable Push, Element must first get a push token from the firebase SDK, then register a pusher with this token on the homeserver.
|
||||
In order to enable Push, RiotX must first get a push token from the firebase SDK, then register a pusher with this token on the HomeServer.
|
||||
|
||||
When a message should be notified to a user, the user's homeserver notifies the registered `push gateway` for Element, that is [sygnal](https://github.com/matrix-org/sygnal) _- The reference implementation for push gateways -_ hosted by matrix.org.
|
||||
When a message should be notified to a user, the user's homeserver notifies the registered `push gateway` for RiotX, that is [sygnal](https://github.com/matrix-org/sygnal) _- The reference implementation for push gateways -_ hosted by matrix.org.
|
||||
|
||||
This sygnal instance is configured with the required FCM API authentication token, and will then use the FCM API in order to notify the user's device running Element.
|
||||
This sygnal instance is configured with the required FCM API authentication token, and will then use the FCM API in order to notify the user's device running riotX.
|
||||
|
||||
```
|
||||
Homeserver ----> Sygnal (configured for Element) ----> FCM ----> Element
|
||||
Homeserver ----> Sygnal (configured for RiotX) ----> FCM ----> RiotX
|
||||
```
|
||||
|
||||
The push gateway is configured to only send `(eventId,roomId)` in the push payload (for better [privacy](#push-vs-privacy-and-mitigation)).
|
||||
|
||||
Element needs then to synchronise with the user's homeserver, in order to resolve the event and create a notification.
|
||||
RiotX needs then to synchronise with the user's HomeServer, in order to resolve the event and create a notification.
|
||||
|
||||
As per [Google recommendation](https://android-developers.googleblog.com/2018/09/notifying-your-users-with-fcm.html), Element will then use the WorkManager API in order to trigger a background sync.
|
||||
As per [Google recommendation](https://android-developers.googleblog.com/2018/09/notifying-your-users-with-fcm.html), RiotX will then use the WorkManager API in order to trigger a background sync.
|
||||
|
||||
**Google recommendations:**
|
||||
> We recommend using FCM messages in combination with the WorkManager 1 or JobScheduler API
|
||||
@@ -214,7 +209,7 @@ As per [Google recommendation](https://android-developers.googleblog.com/2018/09
|
||||
> Avoid background services. One common pitfall is using a background service to fetch data in the FCM message handler, since background service will be stopped by the system per recent changes to Google Play Policy
|
||||
|
||||
```
|
||||
Homeserver ----> Sygnal ----> FCM ----> Element
|
||||
Homeserver ----> Sygnal ----> FCM ----> RiotX
|
||||
(Sync) ----> Homeserver
|
||||
<----
|
||||
Display notification
|
||||
@@ -222,24 +217,24 @@ Homeserver ----> Sygnal ----> FCM ----> Element
|
||||
|
||||
**Possible outcomes**
|
||||
|
||||
Upon reception of the FCM push, Element will perform a sync call to the homeserver, during this process it is possible that:
|
||||
Upon reception of the FCM push, RiotX will perform a sync call to the Home Server, during this process it is possible that:
|
||||
* Happy path, the sync is performed, the message resolved and displayed in the notification drawer
|
||||
* The notified message is not in the sync. Can happen if a lot of things did happen since the push (`gappy sync`)
|
||||
* The sync generates additional notifications (e.g an encrypted message where the user is mentioned detected locally)
|
||||
* The sync takes too long and the process is killed before completion, or network is not reliable and the sync fails.
|
||||
|
||||
Element implements several strategies in these cases (TODO document)
|
||||
RiotX implements several strategies in these cases (TODO document)
|
||||
|
||||
### FCM Fallback mode
|
||||
## FCM Fallback mode
|
||||
|
||||
It is possible that Element is not able to get a FCM push token.
|
||||
Common errors (among several others) that can cause that:
|
||||
It is possible that RiotX is not able to get a FCM push token.
|
||||
Common errors (amoung several others) that can cause that:
|
||||
* Google Play Services is outdated
|
||||
* Google Play Service fails in someways with FCM servers (infamous `SERVICE_NOT_AVAILABLE`)
|
||||
|
||||
If Element is able to detect one of this cases, it will notifies it to the users and when possible help him fix it via a dedicated troubleshoot screen.
|
||||
If RiotX is able to detect one of this cases, it will notifies it to the users and when possible help him fix it via a dedicated troubleshoot screen.
|
||||
|
||||
Meanwhile, in order to offer a minimal service, and as per Google's recommendation for background activities, Element will launch periodic background sync in order to stays in sync with servers.
|
||||
Meanwhile, in order to offer a minimal service, and as per Google's recommendation for background activities, RiotX will launch periodic background sync in order to stays in sync with servers.
|
||||
|
||||
The fallback mode is impacted by all the battery life saving mechanism implemented by android. Meaning that if the app is not used for a certain amount of time (`App-Standby`), or the device stays still and unplugged (`Light Doze`) , the sync will become less frequent.
|
||||
|
||||
@@ -251,9 +246,9 @@ Usually in this mode, what happen is when you take back your phone in your hand,
|
||||
|
||||
The fallback mode is supposed to be a temporary state waiting for the user to fix issues for FCM, or for App Developers that has done a fork to correctly configure their FCM settings.
|
||||
|
||||
### F-Droid background Mode
|
||||
## F-Droid background Mode
|
||||
|
||||
The F-Droid Element flavor has no dependencies to FCM, therefore cannot relies on Push.
|
||||
The F-Droid RiotX flavor has no dependencies to FCM, therefore cannot relies on Push.
|
||||
|
||||
Also Google's recommended background processing method cannot be applied. This is because all of these methods are affected by IDLE modes, and will result on the user not being notified at all when the app is in a Doze mode (only in maintenance windows that could happens only after hours).
|
||||
|
||||
@@ -261,17 +256,19 @@ Only solution left is to use `AlarmManager`, that offers new API to allow launch
|
||||
|
||||
Notice that these alarms, due to their potential impact on battery life, can still be restricted by the system. Documentation says that they will not be triggered more than every minutes under normal system operation, and when in low power mode about every 15 mn.
|
||||
|
||||
These restrictions can be relaxed by requiring the app to be white listed from battery optimization.
|
||||
These restrictions can be relaxed by requirering the app to be white listed from battery optimization.
|
||||
|
||||
F-Droid version will schedule alarms that will then trigger a Broadcast Receiver, that in turn will launch a Service (in the classic android way), and the reschedule an alarm for next time.
|
||||
|
||||
Depending on the system status (or device make), it is still possible that the app is not given enough time to launch the service, or that the radio is still turned off thus preventing the sync to success (that's why Alarms are not recommended for network related tasks).
|
||||
|
||||
That is why on Element F-Droid, the broadcast receiver will acquire a temporary WAKE_LOCK for several seconds (thus securing cpu/network), and launch the service in foreground. The service performs the sync.
|
||||
That is why on RiotX F-Droid, the broadcast receiver will acquire a temporary WAKE_LOCK for several seconds (thus securing cpu/network), and launch the service in foreground. The service performs the sync.
|
||||
|
||||
Note that foreground services require to put a notification informing the user that the app is doing something even if not launched).
|
||||
|
||||
## Application Settings
|
||||
|
||||
|
||||
# Application Settings
|
||||
|
||||
**Notifications > Enable notifications for this account**
|
||||
|
||||
|
@@ -1,290 +0,0 @@
|
||||
# Pull requests
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Who should read this document?](#who-should-read-this-document?)
|
||||
* [Submitting PR](#submitting-pr)
|
||||
* [Who can submit pull requests?](#who-can-submit-pull-requests?)
|
||||
* [Humans](#humans)
|
||||
* [Draft PR?](#draft-pr?)
|
||||
* [Base branch](#base-branch)
|
||||
* [PR Review Assignment](#pr-review-assignment)
|
||||
* [PR review time](#pr-review-time)
|
||||
* [Re-request PR review](#re-request-pr-review)
|
||||
* [When create split PR?](#when-create-split-pr?)
|
||||
* [Avoid fixing other unrelated issue in a big PR](#avoid-fixing-other-unrelated-issue-in-a-big-pr)
|
||||
* [Bots](#bots)
|
||||
* [Dependabot](#dependabot)
|
||||
* [Gradle wrapper](#gradle-wrapper)
|
||||
* [Sync analytics plan](#sync-analytics-plan)
|
||||
* [Reviewing PR](#reviewing-pr)
|
||||
* [Who can review pull requests?](#who-can-review-pull-requests?)
|
||||
* [What to have in mind when reviewing a PR](#what-to-have-in-mind-when-reviewing-a-pr)
|
||||
* [Rules](#rules)
|
||||
* [Check the form](#check-the-form)
|
||||
* [PR title](#pr-title)
|
||||
* [PR description](#pr-description)
|
||||
* [File change](#file-change)
|
||||
* [Check the commit](#check-the-commit)
|
||||
* [Check the substance](#check-the-substance)
|
||||
* [Make a dedicated meeting to review the PR](#make-a-dedicated-meeting-to-review-the-pr)
|
||||
* [What happen to the issue(s)?](#what-happen-to-the-issues?)
|
||||
* [Merge conflict](#merge-conflict)
|
||||
* [When and who can merge PR](#when-and-who-can-merge-pr)
|
||||
* [Merge type](#merge-type)
|
||||
* [Resolve conversation](#resolve-conversation)
|
||||
* [Responsibility](#responsibility)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
## Introduction
|
||||
|
||||
This document gives some clue about how to efficiently manage Pull Requests (PR). This document is a first draft and may be improved later.
|
||||
|
||||
## Who should read this document?
|
||||
|
||||
Every pull request reviewers, but also probably every ones who submit PRs.
|
||||
|
||||
## Submitting PR
|
||||
|
||||
### Who can submit pull requests?
|
||||
|
||||
Basically every one who wants to contribute to the project! But there are some rules to follow.
|
||||
|
||||
#### Humans
|
||||
|
||||
People with write access to the project can directly clone the project, push their branches and create PR.
|
||||
|
||||
External contributors must first fork the project and create PR to the mainline from there.
|
||||
|
||||
##### Draft PR?
|
||||
|
||||
Draft PR can be created when the submitter does not expect the PR to be reviewed and merged yet. It can be useful to publicly show the work, or to do a self-review first.
|
||||
|
||||
Draft PR can also be created when it depends on other un-merged PR.
|
||||
|
||||
In any case, it is better to explicitly declare in the description why the PR is a draft PR.
|
||||
|
||||
Also, draft PR should not stay indefinitely in this state. It may be removed if it is the case and the submitter does not update it after a few days.
|
||||
|
||||
##### Base branch
|
||||
|
||||
The `develop` branch is generally the base branch for every PRs.
|
||||
|
||||
Exceptions can occur:
|
||||
|
||||
- if a feature implementation is split into multiple PRs. We can have a chain of PRs in this case. PR can be merged one by one on develop, and GitHub change the target branch to `develop` for the next PR automatically.
|
||||
- we want to merge a PR from the community, but there is still work to do, and the PR is not updated by the submitter. First, we can kindly ask the submitter if they will update their PR, by commenting it. If there is no answer after a few days (including a week-end), we can create a new branch, push it, and change the target branch of the PR to this new branch. The PR can then be merged, and we can add more commits to fix the issues. After that a new PR can be created with `develop` as a target branch.
|
||||
|
||||
**Important notice 1:** Releases are created from the `develop` branch. So `develop` branch should always contain a "releasable" source code. So when a feature is being implemented with several PRs, it has to be disabled by default (using a feature flag for instance), until the feature is fully implemented. A last PR to enable the feature can then be created.
|
||||
|
||||
**Important notice 2:** Database migration: some developers and some people from the community are using the nightly build from `develop`. Multiple database migrations should be properly handled for them. This is OK to have multiple migrations between 2 releases, this is not OK to add steps to the pending database migration on `develop`. So for instance `develop` users will migrate from version 11 to version 12, then 13, then 14, and `main` users will do all those steps after they get the app upgrade.
|
||||
|
||||
##### PR Review Assignment
|
||||
|
||||
We use automatic assignment for PR reviews. **A PR is automatically routed by GitHub to one team member** using the round robin algorithm. Additional reviewers can be used for complex changes or when the first reviewer is not confident enough on the changes.
|
||||
The process is the following:
|
||||
|
||||
- The PR creator selects the [element-android-reviewers](https://github.com/orgs/vector-im/teams/element-android-reviewers) team as a reviewer.
|
||||
- GitHub automatically assign the reviewer. If the reviewer is not available (holiday, etc.), remove them and set again the team, GitHub will select another reviewer.
|
||||
- Alternatively, the PR creator can directly assign specific people if they have another Android developer in their team or they think a specific reviewer should take a look at their PR.
|
||||
- Reviewers get a notification to make the review: they review the code following the good practice (see the rest of this document).
|
||||
- After making their own review, if they feel not confident enough, they can ask another person for a full review, or they can tag someone within a PR comment to check specific lines.
|
||||
|
||||
For PRs coming from the community, the issue wrangler can assign either the team [element-android-reviewers](https://github.com/orgs/vector-im/teams/element-android-reviewers) or any member directly.
|
||||
|
||||
##### PR review time
|
||||
|
||||
As a PR submitter, you deserve a quick review. As a reviewer, you should do your best to unblock others.
|
||||
|
||||
Some tips to achieve it:
|
||||
|
||||
- Set up your GH notifications correctly
|
||||
- Check your pulls page: [https://github.com/pulls](https://github.com/pulls)
|
||||
- Check your pending assigned PRs before starting or resuming your day to day tasks
|
||||
- If you are busy with high priority tasks, inform the author. They will find another developer
|
||||
|
||||
It is hard to define a deadline for a review. It depends on the PR size and the complexity. Let's start with a goal of 24h (working day!) for a PR smaller than 500 lines. If bigger, the submitter and the reviewer should discuss.
|
||||
|
||||
After this time, the submitter can ping the reviewer to get a status of the review.
|
||||
|
||||
##### Re-request PR review
|
||||
|
||||
Once all the remarks have been handled, it's possible to re-request a review from the (same) reviewer to let them know that the PR has been updated the PR is ready to be reviewed again. Use the double arrow next to the reviewer name to do that.
|
||||
|
||||
##### When create split PR?
|
||||
|
||||
To implement big new feature, it may be efficient to split the work into several smaller and scoped PRs. They will be easier to review, and they can be merged on `develop` faster.
|
||||
|
||||
Big PR can take time, and there is a risk of future merge conflict.
|
||||
|
||||
Feature flag can be used to avoid half implemented feature to be available in the application.
|
||||
|
||||
That said, splitting into several PRs should not have the side effect to have more review to do, for instance if some code is added, then finally removed.
|
||||
|
||||
##### Avoid fixing other unrelated issue in a big PR
|
||||
|
||||
Each PR should focus on a single task. If other issues may be fixed when working in the area of it, it's preferable to open a dedicated PR.
|
||||
|
||||
It will have the advantage to be reviewed and merged faster, and not interfere with the main PR.
|
||||
|
||||
It's also applicable for code rework (such as renaming for instance), or code formatting. Sometimes, it is more efficient to extract that work to a dedicated PR, and rebase your branch once this "rework" PR has been merged.
|
||||
|
||||
#### Bots
|
||||
|
||||
Some bots can create PR, but they still have to be reviewed by the team
|
||||
|
||||
##### Dependabot
|
||||
|
||||
Dependabot is a tool which maintain all our external dependencies up to date. A dedicated PR is created for each new available release for one of our external dependency.Dependabot
|
||||
|
||||
To review such PR, you have to
|
||||
- **IMPORTANT** check the diff files (as always).
|
||||
- Check the release note. Some existing bugs in Element project may be fixed by the upgrade
|
||||
- Make sure that the CI is happy
|
||||
- If the code does not compile (API break for instance), you have to checkout the branch and push new commits
|
||||
- Do some smoke test, depending of the library which has been upgraded
|
||||
|
||||
For some reason dependabot sometimes does not upgrade some dependencies. In this case, and when detected, the upgrade has to be done manually.
|
||||
|
||||
##### Gradle wrapper
|
||||
|
||||
`Update Gradle Wrapper` is a tool which can create PR to upgrade our gradle.properties file.
|
||||
Review such PR is the same recipe than for PR from Dependabot
|
||||
|
||||
##### Sync analytics plan
|
||||
|
||||
This tools imports any update in the analytics plan. See instruction in the PR itself to handle it.
|
||||
More info can be found in the file [analytics.md](./analytics.md)
|
||||
|
||||
## Reviewing PR
|
||||
|
||||
### Who can review pull requests?
|
||||
|
||||
As an open source project, every one can review each others PR. Of course an approval from internal developer is mandatory for a PR to be merged.
|
||||
But comment in PR from the community are always appreciated!
|
||||
|
||||
### What to have in mind when reviewing a PR
|
||||
|
||||
1. User experience: is the UX and UI correct? You will probably be the second person to test the new thing, the first one is the developer.
|
||||
2. Developer experience: does the code look nice and decoupled? No big functions, new classes added to the right module, etc.
|
||||
3. Code maintenance. A bit similar to point 2. Tricky code must be documented for instance
|
||||
4. Fork consideration. Will configuration of forks be easy? Some documentation may help in some cases.
|
||||
5. We are building long term products. "Quick and dirty" code must be avoided.
|
||||
6. The PR includes new tests for the added code, updated test for the existing code
|
||||
7. All PRs from external contributors **MUST** include a sign-off. It's in the checklist, and sometimes it's checked by the submitter, but there is actually no sign-off. In this case, ask nicely for a sign-off and request changes (do not approve the PR, even if everything else is fine).
|
||||
|
||||
### Rules
|
||||
|
||||
#### Check the form
|
||||
|
||||
##### PR title
|
||||
|
||||
PR title should describe in one line what's brought by the PR. Reviewer can edit the title if it's not clear enough, or to add suffix like `[BLOCKED]` or similar. Fixing typo is also a good practice, since GitHub search is quite not efficient, so the words must be spelled without any issue. Adding suffix will help when viewing the PR list.
|
||||
|
||||
It's free form, but prefix tags could also be used to help understand what's in the PR.
|
||||
|
||||
Examples of prefixes:
|
||||
- `[Refacto]`
|
||||
- `[Feature]`
|
||||
- `[Bugfix]`
|
||||
- etc.
|
||||
|
||||
Also, it's still possible to add labels to the PRs, such as `A-` or `T-` labels, even if this is not a strong requirement. We prefer to spend time to add labels on issues.
|
||||
|
||||
##### PR description
|
||||
|
||||
PR description should follow the PR template, and at least provide some context about the code change.
|
||||
|
||||
##### File change
|
||||
|
||||
1. Code should follow the guidelines
|
||||
2. Code should be formatted correctly
|
||||
3. XML attribute must be sorted
|
||||
4. New code is added at the correct location
|
||||
5. New classes are added to the correct location
|
||||
6. Naming is correct. Naming is really important, it's considered part of the documentation
|
||||
7. Architecture is followed. For instance, the logic is in the ViewModel and not in the Fragment
|
||||
8. There is at least one file for the changelog. Exception if the PR fixes something which has not been released yet. Changelog content should target their audience: `.sdk` extension are mainly targeted for developers, other extensions are targeted for users and forks maintainers. It should generally describe visual change rather than give technical details. More details can be found [here](../CONTRIBUTING.md#changelog).
|
||||
9. PR includes tests. allScreensTest when applicable, and unit tests
|
||||
10. Avoid over complicating things. Keep it simple (KISS)!
|
||||
11. PR contains only the expected change. Sometimes, the diff is showing changes that are already on `develop`. This is not good, submitter has to fix that up.
|
||||
|
||||
##### Check the commit
|
||||
|
||||
Commit message must be short, one line and valuable. "WIP" is not a good commit message. Commit message can contain issue number, starting with `#`. GitHub will add some link between the issue and such commit, which can be useful. It's possible to change a commit message at any time (may require a force push).
|
||||
|
||||
Commit messages can contain extra lines with more details, links, etc. But keep in mind that those lines are quite less visible than the first line.
|
||||
|
||||
Also commit history should be nice. Having commits like "Adding temporary code" then later "Removing temporary code" is not good. The branch has to be rebased and those commit have to be dropped.
|
||||
|
||||
PR merger could decide to squash and merge if commit history is not good.
|
||||
|
||||
Commit like "Code review fixes" is good when reviewing the PR, since new changes can be reviewed easily, but is less valuable when looking at git history. To avoid this, PR submitter should always push new commits after a review (no commit amend with force push), and when the PR is approved decide to interactive rebase the PR to improve the git history and reduce noise.
|
||||
|
||||
##### Check the substance
|
||||
|
||||
1. Test the changes!
|
||||
2. Test the nominal case and the edge cases
|
||||
3. Run the sanity test for critical PR
|
||||
|
||||
##### Make a dedicated meeting to review the PR
|
||||
|
||||
Sometimes a big PR can be hard to review. Setting up a call with the PR submitter can speed up the communication, rather than putting comments and questions in GitHub comments. It has the inconvenience of making the discussion non-public, consider including a summary of the main points of the "offline" conversation in the PR.
|
||||
|
||||
### What happen to the issue(s)?
|
||||
|
||||
The issue(s) should be referenced in the PR description using keywords like `Closes` of `Fixes` followed by the issue number.
|
||||
|
||||
Example:
|
||||
> Closes #1
|
||||
|
||||
Note that you have to repeat the keyword in case of a list of issue
|
||||
|
||||
> Closes #1, Closes #2, etc.
|
||||
|
||||
When PR will be merged, such referenced issue will be automatically closed.
|
||||
It is up to the person who has merged the PR to go to the (closed) issue(s) and to add a comment to inform in which version the issue fix will be available. Use the current version of `develop` branch.
|
||||
|
||||
> Closed in Element Android v1.x.y
|
||||
|
||||
### Merge conflict
|
||||
|
||||
It's up to the submitter to handle merge conflict. Sometimes, they can be fixed directly from GitHub, sometimes this is not possible. The branch can be rebased on `develop`, or the `develop` branch can be merged on the branch, it's up to the submitter to decide what is best.
|
||||
Keep in mind that Github Actions are not run in case of conflict.
|
||||
|
||||
### When and who can merge PR
|
||||
|
||||
PR can be merged by the submitter, if and only if at least one approval from another developer is done. Approval from all people added as reviewer is also a good thing to have. Approval from design team may be mandatory, but is not sufficient to merge a PR.
|
||||
|
||||
PR can also be merged by the reviewer, to reduce the time the PR is open. But only if the PR is not in draft and the change are quite small, or behind a feature flag.
|
||||
|
||||
Dangerous PR should not be merged just before a release. Dangerous PR are PR that could break the app. Update of Realm library, rework in the chunk of Events management in the SDK, etc.
|
||||
|
||||
We prefer to merge such PR after a release so that it can be tested during several days by the team before behind included in a release candidate.
|
||||
|
||||
PR from bots will always be merged by the reviewer, right after approving the changes, or in case of critical changes, right after a release.
|
||||
|
||||
#### Merge type
|
||||
|
||||
Generally we use "Create a merge commit", which has the advantage to keep the branch visible.
|
||||
|
||||
If git history is noisy (code added, then removed, etc.), it's possible to use "Squash and merge". But the branch will not be visible anymore, a commit will be added on top of develop. Git commit message can (and probably must) be edited from the GitHub web app. It's better if the submitter do the work to cleanup the git history by using a git interactive rebase of their branch.
|
||||
|
||||
### Resolve conversation
|
||||
|
||||
Generally we do not close conversation added during PR review and update by clicking on "Resolve conversation"
|
||||
If the submitter or the reviewer do so, it will more difficult for further readers to see again the content. They will have to open the conversation to see it again. it's a waste of time.
|
||||
|
||||
When remarks are handled, a small comment like "done" is enough, commit hash can also be added to the conversation.
|
||||
|
||||
Exception: for big PRs with lots of conversations, using "Resolve conversation" may help to see the remaining remarks.
|
||||
|
||||
Also "Resolve conversation" should probably be hit by the creator of the conversation.
|
||||
|
||||
## Responsibility
|
||||
|
||||
PR submitter is responsible of the incoming change. PR reviewers who approved the PR take a part of responsibility on the code which will land to develop, and then be used by our users, and the user of our forks.
|
||||
|
||||
That said, bug may still be merged on `develop`, this is still acceptable of course. In this case, please make sure an issue is created and correctly labelled. Ideally, such issues should be fixed before the next release candidate, i.e. with a higher priority. But as we release the application every 10 working days, it can be hard to fix every bugs. That's why PR should be fully tested and reviewed before being merge and we should never comment code review remark with "will be handled later", or similar comments.
|
@@ -1,41 +0,0 @@
|
||||
Useful links:
|
||||
- https://github.com/ReactiveCircus/FlowBinding
|
||||
- https://ivanisidrowu.github.io/kotlin/2020/08/09/Kotlin-Flow-Migration-And-Testing.html
|
||||
|
||||
|
||||
Rx is now completely removed from Element dependencies.
|
||||
Some examples of the changes:
|
||||
|
||||
```
|
||||
sharedActionViewModel
|
||||
.observe()
|
||||
.subscribe { handleQuickActions(it) }
|
||||
.disposeOnDestroyView()
|
||||
```
|
||||
|
||||
became
|
||||
|
||||
```
|
||||
sharedActionViewModel
|
||||
.stream()
|
||||
.onEach { handleQuickActions(it) }
|
||||
.launchIn(viewLifecycleOwner.lifecycleScope)
|
||||
|
||||
```
|
||||
|
||||
Inside fragment use
|
||||
```
|
||||
launchIn(viewLifecycleOwner.lifecycleScope)
|
||||
```
|
||||
Inside activity use
|
||||
```
|
||||
launchIn(lifecycleScope)
|
||||
```
|
||||
Inside viewModel use
|
||||
```
|
||||
launchIn(viewModelScope)
|
||||
```
|
||||
|
||||
Also be aware that when using these scopes the coroutine is launched on Dispatchers.Main by default.
|
||||
|
||||
|
116
docs/signin.md
116
docs/signin.md
@@ -2,36 +2,13 @@
|
||||
|
||||
This document describes the flow of signin to a homeserver, and also the flow when user want to reset his password. Examples come from the `matrix.org` homeserver.
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Sign in flows](#sign-in-flows)
|
||||
* [Get the flow](#get-the-flow)
|
||||
* [Login with username](#login-with-username)
|
||||
* [Incorrect password](#incorrect-password)
|
||||
* [Correct password:](#correct-password:)
|
||||
* [Login with email](#login-with-email)
|
||||
* [Unknown email](#unknown-email)
|
||||
* [Known email, wrong password](#known-email-wrong-password)
|
||||
* [Known email, correct password](#known-email-correct-password)
|
||||
* [Login with Msisdn](#login-with-msisdn)
|
||||
* [Login with SSO](#login-with-sso)
|
||||
* [Reset password](#reset-password)
|
||||
* [Send email](#send-email)
|
||||
* [When the email is not known](#when-the-email-is-not-known)
|
||||
* [When the email is known](#when-the-email-is-known)
|
||||
* [User clicks on the link](#user-clicks-on-the-link)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
## Sign in flows
|
||||
## Sign up flows
|
||||
|
||||
### Get the flow
|
||||
|
||||
Client request the sign-in flows, once the homeserver is chosen by the user and its url is known (in the example it's `https://matrix.org`)
|
||||
|
||||
```shell script
|
||||
curl -X GET 'https://matrix.org/_matrix/client/r0/login'
|
||||
```
|
||||
> curl -X GET 'https://matrix.org/_matrix/client/r0/login'
|
||||
|
||||
200
|
||||
|
||||
@@ -49,9 +26,7 @@ curl -X GET 'https://matrix.org/_matrix/client/r0/login'
|
||||
|
||||
The user is able to connect using `m.login.password`
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"identifier":{"type":"m.id.user","user":"alice"},"password":"weak_password","type":"m.login.password","initial_device_display_name":"Portable"}' 'https://matrix.org/_matrix/client/r0/login'
|
||||
```
|
||||
> curl -X POST --data $'{"identifier":{"type":"m.id.user","user":"alice"},"password":"weak_password","type":"m.login.password","initial_device_display_name":"Portable"}' 'https://matrix.org/_matrix/client/r0/login'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -82,8 +57,8 @@ We get credential (200)
|
||||
|
||||
```json
|
||||
{
|
||||
"user_id": "@alice:matrix.org",
|
||||
"access_token": "MDAxOGxvY2F0aW9uIG1hdHREDACTEDb2l0MDgxNjptYXRyaXgub3JnCjAwMTZjaWQgdHlwZSA9IGFjY2VzcwowMDIxY2lr",
|
||||
"user_id": "@benoit0816:matrix.org",
|
||||
"access_token": "MDAxOGxvY2F0aW9uIG1hdHREDACTEDb2l0MDgxNjptYXRyaXgub3JnCjAwMTZjaWQgdHlwZSA9IGFjY2VzcwowMDIxY2lkIG5vbmNlID0gfnYrSypfdTtkNXIuNWx1KgowMDJmc2lnbmF0dXJlIOsh1XqeAkXexh4qcofl_aR4kHJoSOWYGOhE7-ubX-DZCg",
|
||||
"home_server": "matrix.org",
|
||||
"device_id": "GTVREDALBF",
|
||||
"well_known": {
|
||||
@@ -98,16 +73,14 @@ We get credential (200)
|
||||
|
||||
If the user has associated an email with its account, he can signin using the email.
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"identifier":{"type":"m.id.thirdparty","medium":"email","address":"alice@email-provider.org"},"password":"weak_password","type":"m.login.password","initial_device_display_name":"Portable"}' 'https://matrix.org/_matrix/client/r0/login'
|
||||
```
|
||||
> curl -X POST --data $'{"identifier":{"type":"m.id.thirdparty","medium":"email","address":"alice@yopmail.com"},"password":"weak_password","type":"m.login.password","initial_device_display_name":"Portable"}' 'https://matrix.org/_matrix/client/r0/login'
|
||||
|
||||
```json
|
||||
{
|
||||
"identifier": {
|
||||
"type": "m.id.thirdparty",
|
||||
"medium": "email",
|
||||
"address": "alice@email-provider.org"
|
||||
"address": "alice@yopmail.com"
|
||||
},
|
||||
"password": "weak_password",
|
||||
"type": "m.login.password",
|
||||
@@ -144,7 +117,7 @@ We get the credentials (200)
|
||||
```json
|
||||
{
|
||||
"user_id": "@alice:matrix.org",
|
||||
"access_token": "MDAxOGxvY2F0aW9uIG1hdHJpeC5vcmREDACTEDZXJfaWQgPSBAYmVub2l0MDgxNjptYXRyaXgub3Jnfrfdegfszsefddvf",
|
||||
"access_token": "MDAxOGxvY2F0aW9uIG1hdHJpeC5vcmREDACTEDZXJfaWQgPSBAYmVub2l0MDgxNjptYXRyaXgub3JnCjAwMTZjaWQgdHlwZSA9IGFjY2VzcwowMDIxY2lkIG5vbmNlID0gNjtDY0MwRlNPSFFoOC5wOgowMDJmc2lnbmF0dXJlIGiTRm1mYLLxQywxOh3qzQVT8HoEorSokEP2u-bAwtnYCg",
|
||||
"home_server": "matrix.org",
|
||||
"device_id": "WBSREDASND",
|
||||
"well_known": {
|
||||
@@ -155,17 +128,13 @@ We get the credentials (200)
|
||||
}
|
||||
```
|
||||
|
||||
It's worth noting that the response from the homeserver contains the userId of Alice.
|
||||
|
||||
### Login with Msisdn
|
||||
|
||||
Not supported yet in Element
|
||||
Not supported yet in RiotX
|
||||
|
||||
### Login with SSO
|
||||
|
||||
```shell script
|
||||
curl -X GET 'https://homeserver.with.sso/_matrix/client/r0/login'
|
||||
```
|
||||
> curl -X GET 'https://homeserver.with.sso/_matrix/client/r0/login'
|
||||
|
||||
200
|
||||
|
||||
@@ -174,61 +143,12 @@ curl -X GET 'https://homeserver.with.sso/_matrix/client/r0/login'
|
||||
"flows": [
|
||||
{
|
||||
"type": "m.login.sso"
|
||||
},
|
||||
{
|
||||
"type": "m.login.token"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
In this case, the user can click on "Sign in with SSO" and the native web browser, or a ChromeCustomTab if the device supports it, will be launched on the page
|
||||
|
||||
> https://homeserver.with.sso/_matrix/client/r0/login/sso/redirect?redirectUrl=element%3A%2F%element
|
||||
|
||||
The parameter `redirectUrl` is set to `element://connect`.
|
||||
|
||||
ChromeCustomTabs are an intermediate way to display a WebPage, between a WebView and using the external browser. More info can be found [here](https://developer.chrome.com/multidevice/android/customtabs)
|
||||
|
||||
The browser will then take care of the SSO login, which may include creating a third party account, entering an email, settings a display name, or any other possibilities.
|
||||
|
||||
During the process, user may be asked to validate an email by clicking on a link it contains. The link has to be opened in the browser which initiates the authentication. This is why we cannot use WebView anymore.
|
||||
|
||||
Once the process is finished, the web page will call the `redirectUrl` with an extra parameter `loginToken`
|
||||
|
||||
> element://connect?loginToken=MDAxOWxvY2F0aW9uIG1vemlsbGEub3JnCjAwMTNpZGVudGlmaWVy
|
||||
|
||||
This navigation is intercepted by Element by the `LoginActivity`, which will then ask the homeserver to convert this `loginToken` to an access token
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"type":"m.login.token","token":"MDAxOWxvY2F0aW9uIG1vemlsbGEub3JnCjAwMTNpZGVudGlmaWVy"}' 'https://homeserver.with.sso/_matrix/client/r0/login'
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "m.login.token",
|
||||
"token": "MDAxOWxvY2F0aW9uIG1vemlsbGEub3JnCjAwMTNpZGVudGlmaWVy"
|
||||
}
|
||||
```
|
||||
|
||||
We get the credentials (200)
|
||||
|
||||
```json
|
||||
{
|
||||
"user_id": "@alice:homeserver.with.sso",
|
||||
"access_token": "MDAxOWxvY2F0aW9uIG1vemlsbGEub3JnCjAwMTNpZGVudGlmaWVyIGtleQowMDEwY2lkIGdlbiA9IDEKMDAyY2NpZCB1c2",
|
||||
"home_server": "homeserver.with.sso",
|
||||
"device_id": "DETBTVAHCH",
|
||||
"well_known": {
|
||||
"m.homeserver": {
|
||||
"base_url": "https:\/\/homeserver.with.sso\/"
|
||||
},
|
||||
"m.identity_server": {
|
||||
"base_url": "https:\/\/vector.im"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
In this case, the user can click on "Sign in with SSO" and the web screen will be displayed on the page `https://homeserver.with.sso/_matrix/static/client/login/` and the credentials will be passed back to the native code through the JS bridge
|
||||
|
||||
## Reset password
|
||||
|
||||
@@ -245,9 +165,7 @@ We display a warning regarding e2e.
|
||||
|
||||
At the first step, we do not send the password, only the email and a client secret, generated by the application
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"client_secret":"6c57f284-85e2-421b-8270-fb1795a120a7","send_attempt":0,"email":"user@domain.com"}' 'https://matrix.org/_matrix/client/r0/account/password/email/requestToken'
|
||||
```
|
||||
> curl -X POST --data $'{"client_secret":"6c57f284-85e2-421b-8270-fb1795a120a7","send_attempt":0,"email":"user@domain.com"}' 'https://matrix.org/_matrix/client/r0/account/password/email/requestToken'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -284,9 +202,7 @@ During this step, the new password is sent to the homeserver.
|
||||
|
||||
If the user confirms before the link is clicked, we get an error:
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"auth":{"type":"m.login.email.identity","threepid_creds":{"client_secret":"6c57f284-85e2-421b-8270-fb1795a120a7","sid":"tQNbrREDACTEDldA"}},"new_password":"weak_password"}' 'https://matrix.org/_matrix/client/r0/account/password'
|
||||
```
|
||||
> curl -X POST --data $'{"auth":{"type":"m.login.email.identity","threepid_creds":{"client_secret":"6c57f284-85e2-421b-8270-fb1795a120a7","sid":"tQNbrREDACTEDldA"}},"new_password":"weak_password"}' 'https://matrix.org/_matrix/client/r0/account/password'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -320,9 +236,7 @@ It contains the client secret, a token and the sid
|
||||
|
||||
When the user click the link, if validate his ownership and the new password can now be ent by the application (on user demand):
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"auth":{"type":"m.login.email.identity","threepid_creds":{"client_secret":"6c57f284-85e2-421b-8270-fb1795a120a7","sid":"tQNbrREDACTEDldA"}},"new_password":"weak_password"}' 'https://matrix.org/_matrix/client/r0/account/password'
|
||||
```
|
||||
> curl -X POST --data $'{"auth":{"type":"m.login.email.identity","threepid_creds":{"client_secret":"6c57f284-85e2-421b-8270-fb1795a120a7","sid":"tQNbrREDACTEDldA"}},"new_password":"weak_password"}' 'https://matrix.org/_matrix/client/r0/account/password'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -343,4 +257,4 @@ curl -X POST --data $'{"auth":{"type":"m.login.email.identity","threepid_creds":
|
||||
{}
|
||||
```
|
||||
|
||||
The password has been changed, and all the existing token are invalidated. User can now login with the new password.
|
||||
The password has been changed, and all the existing token are invalidated. User can now login with the new password.
|
@@ -4,29 +4,13 @@ This document describes the flow of registration to a homeserver. Examples come
|
||||
|
||||
*Ref*: https://matrix.org/docs/spec/client_server/latest#account-registration-and-management
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Sign up flows](#sign-up-flows)
|
||||
* [First step](#first-step)
|
||||
* [Step 1: entering user name and password](#step-1:-entering-user-name-and-password)
|
||||
* [If username already exists](#if-username-already-exists)
|
||||
* [Step 2: entering email](#step-2:-entering-email)
|
||||
* [Step 2 bis: user enters an email](#step-2-bis:-user-enters-an-email)
|
||||
* [Step 3: Accepting T&C](#step-3:-accepting-t&c)
|
||||
* [Step 4: Captcha](#step-4:-captcha)
|
||||
* [Step 5: MSISDN](#step-5:-msisdn)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
## Sign up flows
|
||||
|
||||
### First step
|
||||
|
||||
Client request the sign-up flows, once the homeserver is chosen by the user and its url is known (in the example it's `https://matrix.org`)
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
```
|
||||
> curl -X POST --data $'{}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -86,9 +70,7 @@ If the registration is not possible, we get a 403
|
||||
|
||||
The app is displaying a form to enter username and password.
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"initial_device_display_name":"Mobile device","username":"alice","password": "weak_password"}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
```
|
||||
> curl -X POST --data $'{"initial_device_display_name":"Mobile device","username":"alice","password": "weak_password"}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -151,11 +133,9 @@ We get a 400:
|
||||
|
||||
### Step 2: entering email
|
||||
|
||||
User is proposed to enter an email. User skips this step.
|
||||
User is proposed to enter an email. We skip this step.
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"auth":{"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.dummy"}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
```
|
||||
> curl -X POST --data $'{"auth":{"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.dummy"}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -209,18 +189,16 @@ curl -X POST --data $'{"auth":{"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.l
|
||||
}
|
||||
```
|
||||
|
||||
### Step 2 bis: user enters an email
|
||||
### Step 2 bis: we enter an email
|
||||
|
||||
We request a token to the homeserver. The `client_secret` is generated by the application
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"client_secret":"53e679ea-oRED-ACTED-92b8-3012c49c6cfa","email":"alice@email-provider.org","send_attempt":0}' 'https://matrix.org/_matrix/client/r0/register/email/requestToken'
|
||||
```
|
||||
> curl -X POST --data $'{"client_secret":"53e679ea-oRED-ACTED-92b8-3012c49c6cfa","email":"alice@yopmail.com","send_attempt":0}' 'https://matrix.org/_matrix/client/r0/register/email/requestToken'
|
||||
|
||||
```json
|
||||
{
|
||||
"client_secret": "53e679ea-oRED-ACTED-92b8-3012c49c6cfa",
|
||||
"email": "alice@email-provider.org",
|
||||
"email": "alice@yopmail.com",
|
||||
"send_attempt": 0
|
||||
}
|
||||
```
|
||||
@@ -235,9 +213,7 @@ curl -X POST --data $'{"client_secret":"53e679ea-oRED-ACTED-92b8-3012c49c6cfa","
|
||||
|
||||
And
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"auth":{"threepid_creds":{"client_secret":"53e679ea-oRED-ACTED-92b8-3012c49c6cfa","sid":"qlBCREDACTEDEtgxD"},"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.email.identity"}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
```
|
||||
> curl -X POST --data $'{"auth":{"threepid_creds":{"client_secret":"53e679ea-oRED-ACTED-92b8-3012c49c6cfa","sid":"qlBCREDACTEDEtgxD"},"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.email.identity"}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -263,9 +239,7 @@ We get 401 since the email is not validated yet:
|
||||
|
||||
The app is now polling on
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"auth":{"threepid_creds":{"client_secret":"53e679ea-oRED-ACTED-92b8-3012c49c6cfa","sid":"qlBCREDACTEDEtgxD"},"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.email.identity"}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
```
|
||||
> curl -X POST --data $'{"auth":{"threepid_creds":{"client_secret":"53e679ea-oRED-ACTED-92b8-3012c49c6cfa","sid":"qlBCREDACTEDEtgxD"},"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.email.identity"}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -280,7 +254,7 @@ curl -X POST --data $'{"auth":{"threepid_creds":{"client_secret":"53e679ea-oRED-
|
||||
}
|
||||
```
|
||||
|
||||
User clicks on the link received by email `https://matrix.org/_matrix/client/unstable/registration/email/submit_token?token=vtQjQIZfwdoREDACTEDozrmKYSWlCXsJ&client_secret=53e679ea-oRED-ACTED-92b8-3012c49c6cfa&sid=qlBCREDACTEDEtgxD` which contains:
|
||||
We click on the link received by email `https://matrix.org/_matrix/client/unstable/registration/email/submit_token?token=vtQjQIZfwdoREDACTEDozrmKYSWlCXsJ&client_secret=53e679ea-oRED-ACTED-92b8-3012c49c6cfa&sid=qlBCREDACTEDEtgxD` which contains:
|
||||
- A `token` vtQjQIZfwdoREDACTEDozrmKYSWlCXsJ
|
||||
- The `client_secret`: 53e679ea-oRED-ACTED-92b8-3012c49c6cfa
|
||||
- A `sid`: qlBCREDACTEDEtgxD
|
||||
@@ -332,9 +306,7 @@ Once the link is clicked, the registration request (polling) returns a 401 with
|
||||
|
||||
User is proposed to accept T&C and he accepts them
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"auth":{"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.terms"}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
```
|
||||
> curl -X POST --data $'{"auth":{"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.terms"}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -393,9 +365,7 @@ curl -X POST --data $'{"auth":{"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.l
|
||||
|
||||
User is proposed to prove he is not a robot and he does it:
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"auth":{"response":"03AOLTBLSiGS9GhFDpAMblJ2nlXOmHXqAYJ5OvHCPUjiVLBef3k9snOYI_BDC32-t4D2jv-tpvkaiEI_uloobFd9RUTPpJ7con2hMddbKjSCYqXqcUQFhzhbcX6kw8uBnh2sbwBe80_ihrHGXEoACXQkL0ki1Q0uEtOeW20YBRjbNABsZPpLNZhGIWC0QVXnQ4FouAtZrl3gOAiyM-oG3cgP6M9pcANIAC_7T2P2amAHbtsTlSR9CsazNyS-rtDR9b5MywdtnWN9Aw8fTJb8cXQk_j7nvugMxzofPjSOrPKcr8h5OqPlpUCyxxnFtag6cuaPSUwh43D2L0E-ZX7djzaY2Yh_U2n6HegFNPOQ22CJmfrKwDlodmAfMPvAXyq77n3HpoREDACTEDo3830RHF4BfkGXUaZjctgg-A1mvC17hmQmQpkG7IhDqyw0onU-0vF_-ehCjq_CcQEDpS_O3uiHJaG5xGf-0rhLm57v_wA3deugbsZuO4uTuxZZycN_mKxZ97jlDVBetl9hc_5REPbhcT1w3uzTCSx7Q","session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.recaptcha"}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
```
|
||||
> curl -X POST --data $'{"auth":{"response":"03AOLTBLSiGS9GhFDpAMblJ2nlXOmHXqAYJ5OvHCPUjiVLBef3k9snOYI_BDC32-t4D2jv-tpvkaiEI_uloobFd9RUTPpJ7con2hMddbKjSCYqXqcUQFhzhbcX6kw8uBnh2sbwBe80_ihrHGXEoACXQkL0ki1Q0uEtOeW20YBRjbNABsZPpLNZhGIWC0QVXnQ4FouAtZrl3gOAiyM-oG3cgP6M9pcANIAC_7T2P2amAHbtsTlSR9CsazNyS-rtDR9b5MywdtnWN9Aw8fTJb8cXQk_j7nvugMxzofPjSOrPKcr8h5OqPlpUCyxxnFtag6cuaPSUwh43D2L0E-ZX7djzaY2Yh_U2n6HegFNPOQ22CJmfrKwDlodmAfMPvAXyq77n3HpoREDACTEDo3830RHF4BfkGXUaZjctgg-A1mvC17hmQmQpkG7IhDqyw0onU-0vF_-ehCjq_CcQEDpS_O3uiHJaG5xGf-0rhLm57v_wA3deugbsZuO4uTuxZZycN_mKxZ97jlDVBetl9hc_5REPbhcT1w3uzTCSx7Q","session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.recaptcha"}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -426,11 +396,9 @@ Some homeservers may require the user to enter MSISDN.
|
||||
|
||||
On matrix.org, it's not required, and not even optional, but it's still possible for the app to add a MSISDN during the registration.
|
||||
|
||||
The user enters a phone number and selects a country, the `client_secret` is generated by the application
|
||||
The user enter a phone number and select a country, the `client_secret` is generated by the application
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"client_secret":"d3e285f6-972a-496c-9a22-7915a2db57c7","send_attempt":1,"country":"FR","phone_number":"+33611223344"}' 'https://matrix.org/_matrix/client/r0/register/msisdn/requestToken'
|
||||
```
|
||||
> curl -X POST --data $'{"client_secret":"d3e285f6-972a-496c-9a22-7915a2db57c7","send_attempt":1,"country":"FR","phone_number":"+33611223344"}' 'https://matrix.org/_matrix/client/r0/register/msisdn/requestToken'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -462,11 +430,10 @@ If it is not the case, the homeserver send the SMS and returns some data, especi
|
||||
}
|
||||
```
|
||||
|
||||
When we execute the register request, with the received `sid`, we get an error since the MSISDN is not validated yet:
|
||||
When you execute the register request, with the received `sid`, you get an error since the MSISDN is not validated yet:
|
||||
|
||||
> curl -X POST --data $'{"auth":{"type":"m.login.msisdn","session":"xptUYoREDACTEDogOWAGVnbJQ","threepid_creds":{"client_secret":"d3e285f6-972a-496c-9a22-7915a2db57c7","sid":"1678881798"}}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"auth":{"type":"m.login.msisdn","session":"xptUYoREDACTEDogOWAGVnbJQ","threepid_creds":{"client_secret":"d3e285f6-972a-496c-9a22-7915a2db57c7","sid":"1678881798"}}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
```
|
||||
|
||||
```json
|
||||
"auth": {
|
||||
@@ -525,9 +492,7 @@ There is an issue on Synapse, which return a 401, it sends too much data along w
|
||||
|
||||
The user receive the SMS, he can enter the SMS code in the app, which is sent using the "submit_url" received ie the response of the `requestToken` request:
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"client_secret":"d3e285f6-972a-496c-9a22-7915a2db57c7","sid":"1678881798","token":"123456"}' 'https://matrix.org/_matrix/client/unstable/add_threepid/msisdn/submit_token'
|
||||
```
|
||||
> curl -X POST --data $'{"client_secret":"d3e285f6-972a-496c-9a22-7915a2db57c7","sid":"1678881798","token":"123456"}' 'https://matrix.org/_matrix/client/unstable/add_threepid/msisdn/submit_token'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -555,9 +520,7 @@ And if the code is correct we get a 200 with:
|
||||
|
||||
We can now execute the registration request, to the homeserver
|
||||
|
||||
```shell script
|
||||
curl -X POST --data $'{"auth":{"type":"m.login.msisdn","session":"xptUYoREDACTEDogOWAGVnbJQ","threepid_creds":{"client_secret":"d3e285f6-972a-496c-9a22-7915a2db57c7","sid":"1678881798"}}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
```
|
||||
> curl -X POST --data $'{"auth":{"type":"m.login.msisdn","session":"xptUYoREDACTEDogOWAGVnbJQ","threepid_creds":{"client_secret":"d3e285f6-972a-496c-9a22-7915a2db57c7","sid":"1678881798"}}}' 'https://matrix.org/_matrix/client/r0/register'
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -572,7 +535,7 @@ curl -X POST --data $'{"auth":{"type":"m.login.msisdn","session":"xptUYoREDACTED
|
||||
}
|
||||
```
|
||||
|
||||
Now the homeserver considers that the `m.login.msisdn` step is completed (401):
|
||||
Now the homeserver consider that the `m.login.msisdn` step is completed (401):
|
||||
|
||||
```json
|
||||
{
|
||||
|
193
docs/ui-tests.md
193
docs/ui-tests.md
@@ -1,193 +0,0 @@
|
||||
# Automate user interface tests
|
||||
|
||||
Element Android ensures that some fundamental flows are properly working by running automated user interface tests.
|
||||
Ui tests are using the android [Espresso](https://developer.android.com/training/testing/espresso) library.
|
||||
|
||||
Tests can be run on a real device, or on a virtual device (such as the emulator in Android Studio).
|
||||
|
||||
Currently the test are covering a small set of application flows:
|
||||
- Registration
|
||||
- Self verification via emoji
|
||||
- Self verification via passphrase
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Prerequisites:](#prerequisites:)
|
||||
* [Run the tests](#run-the-tests)
|
||||
* [From the source code](#from-the-source-code)
|
||||
* [From command line](#from-command-line)
|
||||
* [Recipes](#recipes)
|
||||
* [Wait for initial sync](#wait-for-initial-sync)
|
||||
* [Accessing current activity](#accessing-current-activity)
|
||||
* [Interact with other session](#interact-with-other-session)
|
||||
* [Contributing to the UiAllScreensSanityTest](#contributing-to-the-uiallscreenssanitytest)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
## Prerequisites:
|
||||
|
||||
Out of the box, the tests use one of the homeservers (located at http://localhost:8080) of the "Demo Federation of Homeservers" (https://github.com/matrix-org/synapse#running-a-demo-federation-of-synapses).
|
||||
|
||||
You first need to follow instructions to set up Synapse in development mode at https://github.com/matrix-org/synapse#synapse-development. If you have already installed all dependencies, the steps are:
|
||||
|
||||
```shell script
|
||||
$ git clone https://github.com/matrix-org/synapse.git
|
||||
$ cd synapse
|
||||
$ virtualenv -p python3 env
|
||||
$ source env/bin/activate
|
||||
(env) $ python -m pip install --no-use-pep517 -e .
|
||||
```
|
||||
|
||||
Every time you want to launch these test homeservers, type:
|
||||
|
||||
```shell script
|
||||
$ source env/bin/activate
|
||||
(env) $ demo/start.sh --no-rate-limit
|
||||
```
|
||||
|
||||
**Emulator/Device set up**
|
||||
|
||||
When running the test via android studio on a device, you have to disable system animations in order for the test to work properly.
|
||||
|
||||
First, ensure developer mode is enabled:
|
||||
|
||||
- To enable developer options, tap the **Build Number** option 7 times. You can find this option in one of the following locations, depending on your Android version:
|
||||
|
||||
- Android 9 (API level 28) and higher: **Settings > About Phone > Build Number**
|
||||
- Android 8.0.0 (API level 26) and Android 8.1.0 (API level 26): **Settings > System > About Phone > Build Number**
|
||||
- Android 7.1 (API level 25) and lower: **Settings > About Phone > Build Number**
|
||||
|
||||
On your device, under **Settings > Developer options**, disable the following 3 settings:
|
||||
|
||||
- Window animation scale
|
||||
- Transition animation scale
|
||||
- Animator duration scale
|
||||
|
||||
## Run the tests
|
||||
|
||||
Once Synapse is running, and an emulator is running, you can run the UI tests.
|
||||
|
||||
### From the source code
|
||||
|
||||
Click on the green arrow in front of each test. Clicking on the arrow in front of the test class, or from the package directory does not always work (Tests not found issue).
|
||||
|
||||
### From command line
|
||||
|
||||
````shell script
|
||||
./gradlew vector:connectedGplayDebugAndroidTest
|
||||
````
|
||||
|
||||
To run all the tests from the `vector` module.
|
||||
|
||||
In case of trouble, you can try to uninstall the previous installed test APK first with this command:
|
||||
|
||||
```shell script
|
||||
adb uninstall im.vector.app.debug.test
|
||||
```
|
||||
## Recipes
|
||||
|
||||
We added some specific Espresso IdlingResources, and other utilities for matrix related tests
|
||||
|
||||
### Wait for initial sync
|
||||
|
||||
```kotlin
|
||||
// Wait for initial sync and check room list is there
|
||||
withIdlingResource(initialSyncIdlingResource(uiSession)) {
|
||||
onView(withId(R.id.roomListContainer))
|
||||
.check(matches(isDisplayed()))
|
||||
}
|
||||
```
|
||||
|
||||
### Accessing current activity
|
||||
|
||||
```kotlin
|
||||
val activity = EspressoHelper.getCurrentActivity()!!
|
||||
val uiSession = (activity as HomeActivity).activeSessionHolder.getActiveSession()
|
||||
```
|
||||
|
||||
### Interact with other session
|
||||
|
||||
It's possible to create a session via the SDK, and then use this session to interact with the one that the emulator is using (to check verifications for example)
|
||||
|
||||
```kotlin
|
||||
@Before
|
||||
fun initAccount() {
|
||||
val context = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
val matrix = Matrix.getInstance(context)
|
||||
val userName = "foobar_${System.currentTimeMillis()}"
|
||||
existingSession = createAccountAndSync(matrix, userName, password, true)
|
||||
}
|
||||
```
|
||||
|
||||
### Contributing to the UiAllScreensSanityTest
|
||||
|
||||
The `UiAllScreensSanityTest` makes use of the Robot pattern in order to model pages, components and interactions.
|
||||
Each Robot aims to return the UI back to its original state after the interaction, allowing for a reusable and consistent DSL.
|
||||
|
||||
```kotlin
|
||||
// launches and closes settings after executing the block
|
||||
elementRobot.settings {
|
||||
// whilst in the settings, launches and closes the advanced settings sub screen
|
||||
advancedSettings {
|
||||
// crawls all the pages within the advanced settings
|
||||
crawl()
|
||||
}
|
||||
}
|
||||
|
||||
// enables developer mode by navigating to the settings, enabling the toggle and then returning to the starting point to execute the block
|
||||
// on block completion the Robot disables developer mode by navigating back to the settings and finally returning to the original starting point
|
||||
elementRobot.withDeveloperMode {
|
||||
// the same starting point as the example above
|
||||
settings {
|
||||
advancedSettings { crawlDeveloperOptions() }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The Robots used in the example above...
|
||||
|
||||
```kotlin
|
||||
class ElementRobot {
|
||||
fun settings(block: SettingsRobot.() -> Unit) {
|
||||
// double check we're where we think we are
|
||||
waitUntilViewVisible(withId(R.id.bottomNavigationView))
|
||||
|
||||
// navigate to the settings
|
||||
openDrawer()
|
||||
clickOn(R.id.homeDrawerHeaderSettingsView)
|
||||
|
||||
// execute the robot with the context of the settings screen
|
||||
block(SettingsRobot())
|
||||
|
||||
// close the settings and ensure we're back at the starting point
|
||||
pressBack()
|
||||
waitUntilViewVisible(withId(R.id.bottomNavigationView))
|
||||
}
|
||||
|
||||
fun withDeveloperMode(block: ElementRobot.() -> Unit) {
|
||||
settings { toggleDeveloperMode() }
|
||||
block()
|
||||
settings { toggleDeveloperMode() }
|
||||
}
|
||||
}
|
||||
|
||||
class SettingsRobot {
|
||||
fun toggleDeveloperMode() {
|
||||
advancedSettings {
|
||||
toggleDeveloperMode()
|
||||
}
|
||||
}
|
||||
|
||||
fun advancedSettings(block: SettingsAdvancedRobot.() -> Unit) {
|
||||
clickOn(R.string.settings_advanced_settings)
|
||||
block(SettingsAdvancedRobot())
|
||||
pressBack()
|
||||
}
|
||||
}
|
||||
|
||||
class SettingsAdvancedRobot {
|
||||
fun toggleDeveloperMode() {
|
||||
clickOn(R.string.settings_developer_mode_summary)
|
||||
}
|
||||
}
|
||||
```
|
@@ -1,58 +0,0 @@
|
||||
# UnifiedPush
|
||||
|
||||
<!--- TOC -->
|
||||
|
||||
* [Introduction](#introduction)
|
||||
* [Configuration in Element-Android and their forks](#configuration-in-element-android-and-their-forks)
|
||||
* [Enabling and disabling the feature](#enabling-and-disabling-the-feature)
|
||||
* [Override the configuration at runtime](#override-the-configuration-at-runtime)
|
||||
* [Enabling the feature](#enabling-the-feature)
|
||||
* [Disabling the feature](#disabling-the-feature)
|
||||
* [Useful links](#useful-links)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
## Introduction
|
||||
|
||||
The recently started UnifiedPush project is an Android protocol and library for apps to be able to receive distributor-agnostic push notifications.
|
||||
|
||||
The *F-Droid* and *Gplay* flavors of Element Android support UnifiedPush, so the user can use any distributor installed on their devices. This would make it possible to have push notifications without depending on Google services or libraries. Currently, the main distributors are [ntfy](https://ntfy.sh) which does not require any setup (like manual registration) to use the public server and [NextPush](https://github.com/UP-NextPush/android), available as a nextcloud application.
|
||||
|
||||
The *Gplay* variant uses a UnifiedPush library which basically embed a FCM distributor built into the application (so a user doesn't need to do anything other than install the app to get FCM notifications). This variant uses Google Services to receive notifications if the user has not installed any distributor. A [FCM Rewrite Proxy](https://unifiedpush.org/developers/embedded_fcm/#fcm-rewrite-proxy) is not required for Element Android's implementation of the FCM distributor - it will work with an existing Matrix push provider, such as [Sygnal](https://github.com/matrix-org/sygnal).
|
||||
|
||||
The *F-Droid* variant does not use this library to avoid any proprietary blob. It will use a polling service if the user has not installed any distributor.
|
||||
|
||||
In all cases, if there are other distributors available, the user will have to opt-in to one of them in the preferences.
|
||||
|
||||
## Configuration in Element-Android and their forks
|
||||
|
||||
### Enabling and disabling the feature
|
||||
|
||||
Allowing the user to use an alternative distributor can be changed in [Config](../vector-config/src/main/java/im/vector/app/config/Config.kt). The flag is named `ALLOW_EXTERNAL_UNIFIED_PUSH_DISTRIBUTORS`. Default value is `true`.
|
||||
|
||||
#### Override the configuration at runtime
|
||||
|
||||
On debug version, it is possible to override this configuration at runtime, using the `Feature` screen. The Feature is named `Allow external UnifiedPush distributors`.
|
||||
|
||||
#### Enabling the feature
|
||||
|
||||
This is the default behavior of Element Android.
|
||||
|
||||
If `ALLOW_EXTERNAL_UNIFIED_PUSH_DISTRIBUTORS` is set to true, it allows any available external UnifiedPush distributor to be chosen by the user.
|
||||
- For Gplay variant it means that FCM will be used by default, but user can choose another UnifiedPush distributor;
|
||||
- For F-Droid variant, it means that background polling will be used by default, but user can choose another UnifiedPush distributor.
|
||||
- On the UI, the setting to choose an alternative distributor will be visible to the user, and some tests in the notification troubleshoot screen will shown.
|
||||
- For F-Droid, if the user has chosen a distributor, the settings to configure the background polling will be hidden.
|
||||
|
||||
#### Disabling the feature
|
||||
|
||||
If `ALLOW_EXTERNAL_UNIFIED_PUSH_DISTRIBUTORS` is set to false, it prevents the usage of external UnifiedPush distributors.
|
||||
- For Gplay variant it means that only FCM will be used;
|
||||
- For F-Droid variant, it means that only background polling will be used.
|
||||
- On the UI, the setting to choose an alternative distributor will be hidden to the user, and some tests in the notification troubleshoot screen will be hidden.
|
||||
|
||||
### Useful links
|
||||
|
||||
- UnifiedPush official website: [https://unifiedpush.org/](https://unifiedpush.org/)
|
||||
- List of available distributors can be retrieved here: [https://unifiedpush.org/users/distributors/](https://unifiedpush.org/users/distributors/)
|
||||
- UnifiedPush project discussion can occurs here: [#unifiedpush:matrix.org](https://matrix.to/#/#unifiedpush:matrix.org)
|
@@ -1,425 +0,0 @@
|
||||
Useful links:
|
||||
- https://codelabs.developers.google.com/codelabs/webrtc-web/#0
|
||||
- http://webrtc.github.io/webrtc-org/native-code/android/
|
||||
|
||||
|
||||
╔════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║A] Placing a call offer ║
|
||||
║ ║
|
||||
╚════════════════════════════════════════════════╝
|
||||
|
||||
|
||||
|
||||
┌───────────────┐
|
||||
│ Matrix │
|
||||
├───────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
│
|
||||
│
|
||||
│
|
||||
┌─────────────────┐ │ ┌───────────────────────────┐ ┌─────────────────┐
|
||||
│ Caller │ │ Signaling Room │ │ │ Callee │
|
||||
└─────────────────┘ │ ├───────────────────────────┤ └─────────────────┘
|
||||
┌────┐ │ │ │
|
||||
│ 3 │ │ │ ┌────────────────────┐ │
|
||||
┌─────────────────┐──────┴────┴──────────────────────────┼─▶│ m.call.invite │ │ │ ┌─────────────────┐
|
||||
│ │ │ │ │ mx event │ │ │ │
|
||||
│ │ │ └────────────────────┘ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ Element │ │ │ │ │ Element │
|
||||
┌──│ App │ │ │ │ │ App │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ │ │ │ │ │ │ │
|
||||
│ └─────────────────┘ │ │ │ └─────────────────┘
|
||||
┌────┤ ▲ │ │ │
|
||||
│ 1 │ ├────┐ │ └───────────────────────────┘
|
||||
└────┤ │ 2 │ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
|
||||
│ ┌──┴────┴─────────┐ ┌─────────────────┐
|
||||
│ │ │ │ │
|
||||
│ │ │ │ │
|
||||
│ │ WebRtc │ │ WebRtc │
|
||||
└─▶│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
┌────┐
|
||||
│ 1 │ The Caller app get access to system resources (camera, mic), eventually stun/turn servers, define some
|
||||
└────┘ constrains (video quality, format) and pass it to WebRtc in order to create a Peer Call offer
|
||||
|
||||
┌────┐
|
||||
│ 2 │ The WebRtc layer creates a call Offer (sdp) that needs to be sent to callee
|
||||
└────┘
|
||||
|
||||
┌────┐ The app layer, takes the webrtc offer, encapsulate it in a matrix event adds a callId and send it to the other
|
||||
│ 3 │ user via the room
|
||||
└────┘
|
||||
┌──────────────┐
|
||||
│ mx event │
|
||||
├──────────────┴────────┐
|
||||
│ type: m.call.invite │
|
||||
│ + callId │
|
||||
│ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ webrtc sdp │ │
|
||||
│ └──────────────────┘ │
|
||||
└───────────────────────┘
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
╔════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║B] Sending connection establishment info ║
|
||||
║ ║
|
||||
╚════════════════════════════════════════════════╝
|
||||
|
||||
|
||||
|
||||
┌───────────────┐
|
||||
│ Matrix │
|
||||
├───────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
│
|
||||
│
|
||||
│
|
||||
┌─────────────────┐ │ ┌───────────────────────────┐ ┌─────────────────┐
|
||||
│ Caller │ │ Signaling Room │ │ │ Callee │
|
||||
└─────────────────┘ │ ├───────────────────────────┤ └─────────────────┘
|
||||
│ ┌────────────────────┐ │ │
|
||||
│ │ │ m.call.invite │ │
|
||||
┌─────────────────┐ │ │ mx event │ │ │ ┌─────────────────┐
|
||||
│ │ ┌────┐ │ │ └────────────────────┘ │ │ │
|
||||
│ │ │ 3 │ │ ┌────────────────────┐ │ │ │ │
|
||||
│ │──────┴────┴───────┼──────────────────┼─▶│ m.call.candidates │ │ │ │
|
||||
│ Element │ │ │ mx event │ │ │ │ Element │
|
||||
│ App │ │ │ └────────────────────┘ │ │ App │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
│ │ │ │ │ │ │
|
||||
└─────────────────┘ │ │ │ └─────────────────┘
|
||||
▲ │ │ │
|
||||
├────┐ │ └───────────────────────────┘
|
||||
│ 2 │ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
|
||||
┌───────┴────┴────┐ ┌─────────────────┐
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ WebRtc │ ┌───────────────┐ │ WebRtc │
|
||||
│ │ │ Stun / Turn │ │ │
|
||||
│ │ ├───────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ │
|
||||
│ │ │ │ │
|
||||
└─────────────────┘ │ └─────────────────┘
|
||||
▲ │
|
||||
│ │
|
||||
└──────────┬────┬───────────▶ │
|
||||
┌───────────────┐ │ 1 │ │
|
||||
│ │ └────┘ │
|
||||
│ Network Stack │ │
|
||||
│ │ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
|
||||
│ │
|
||||
└───────────────┘
|
||||
|
||||
|
||||
|
||||
|
||||
┌────┐
|
||||
│ 1 │ The WebRtc layer gathers information on how it can be reach by the other peer directly (Ice candidates)
|
||||
└────┘
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│candidate:1 1 tcp 1518149375 127.0.0.1 35990 typ host │
|
||||
└──────────────────────────────────────────────────────────────────┘
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│candidate:2 1 UDP 2130706431 192.168.1.102 1816 typ host │
|
||||
└──────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌────┐
|
||||
│ 2 │ The WebRTC layer notifies the App layer when it finds new Ice Candidates
|
||||
└────┘
|
||||
|
||||
|
||||
|
||||
┌────┐ The app layer, takes the ice candidates, encapsulate them in one or several matrix event adds the callId and
|
||||
│ 3 │ send it to the other user via the room
|
||||
└────┘
|
||||
┌──────────────┐
|
||||
│ mx event │
|
||||
├──────────────┴────────────────────────┐
|
||||
│ type: m.call.candidates │
|
||||
│ │
|
||||
│ +CallId │
|
||||
│ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ice candidate sdp │ │
|
||||
│ └──────────────────┘ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ice candidate sdp │ │
|
||||
│ └──────────────────┘ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ice candidate sdp │ │
|
||||
│ └──────────────────┘ │
|
||||
└───────────────────────────────────────┘
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
╔════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║C] Receiving a call offer ║
|
||||
║ ║
|
||||
╚════════════════════════════════════════════════╝
|
||||
|
||||
|
||||
|
||||
┌───────────────┐
|
||||
│ Matrix │
|
||||
├───────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
│
|
||||
│ ┌─────────────────┐
|
||||
│ │ Callee │
|
||||
┌─────────────────┐ │ ┌───────────────────────────┐ └─────────────────┘
|
||||
│ Caller │ │ Signaling Room │ │
|
||||
└─────────────────┘ │ ├───────────────────────────┤
|
||||
│ ┌────────────────────┐ │ │ ┌─────────────────┐
|
||||
│ │ │ m.call.invite │───┼────────────────────────────┬────┬───▶│ │
|
||||
┌─────────────────┐ │ │ mx event │ │ │ │ 1 │ │ │
|
||||
│ │ │ │ └────────────────────┘ │ └────┘ │ │
|
||||
│ │ │ ┌────────────────────┐ │ │ │ Element │
|
||||
│ │ │ │ │ m.call.candidates │ │ │ App │
|
||||
│ Element │ │ │ mx event │ │ │ │ │
|
||||
│ App │ │ │ └────────────────────┘ │ │ │
|
||||
│ │ │ ┌────────────────────┐◀──┼─────────────────┼───┬────┬───────────┤ │
|
||||
│ │◀──────────────────┼──────────────────┼──│ m.call.answer │ │ │ 4 │ └──┬──────────────┘
|
||||
│ │ │ │ mx event │ │ │ └────┘ ├────┐ ▲
|
||||
└────┬────────────┘ │ │ └────────────────────┘ │ │ 2 │ ├────┐
|
||||
│ │ │ │ ├────┘ │ 3 │
|
||||
│ │ └───────────────────────────┘ ┌──▼─────────┴────┤
|
||||
┌────▼────────────┐ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘ │ │
|
||||
│ │ │ │
|
||||
│ │ │ WebRtc │
|
||||
│ WebRtc │ │ ┌──┴─────────────────┐
|
||||
│ │ │ │ caller offer │
|
||||
┌──────────┴─────────┐ │ │ └──┬─────────────────┘
|
||||
│ callee answer │ │ └─────────────────┘
|
||||
└────────────────────┴───────┘
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
┌────┐
|
||||
│ 1 │ Bob receives a call.invite event in a room, then creates a WebRTC peer connection object
|
||||
└────┘
|
||||
|
||||
┌────┐
|
||||
│ 2 │ The encapsulated call offer sdp from the mx event is transmitted to WebRTC
|
||||
└────┘
|
||||
|
||||
┌────┐
|
||||
│ 3 │ WebRTC then creates a call answer for the offer and send it back to app layer
|
||||
└────┘
|
||||
|
||||
|
||||
┌────┐ The app layer, takes the webrtc answer, encapsulate it in a matrix event adds a callId and send it to the
|
||||
│ 3 │ other user via the room
|
||||
└────┘
|
||||
┌──────────────┐
|
||||
│ mx event │
|
||||
├──────────────┴────────┐
|
||||
│ type: m.call.answer │
|
||||
│ + callId │
|
||||
│ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ webrtc sdp │ │
|
||||
│ └──────────────────┘ │
|
||||
└───────────────────────┘
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
╔════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║D] Callee sends connection establishment info ║
|
||||
║ ║
|
||||
╚════════════════════════════════════════════════╝
|
||||
|
||||
|
||||
|
||||
┌───────────────┐
|
||||
│ Matrix │
|
||||
├───────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
│
|
||||
│
|
||||
│
|
||||
┌─────────────────┐ │ ┌───────────────────────────┐ ┌─────────────────┐
|
||||
│ Caller │ │ Signaling Room │ │ │ Callee │
|
||||
└─────────────────┘ │ ├───────────────────────────┤ └─────────────────┘
|
||||
│ ┌────────────────────┐ │ │
|
||||
│ │ │ m.call.invite │ │
|
||||
┌─────────────────┐ │ │ mx event │ │ │ ┌─────────────────┐
|
||||
│ │ │ │ └────────────────────┘ │ │ │
|
||||
│ │ │ ┌────────────────────┐ │ │ │ │
|
||||
│ │ │ │ │ m.call.candidates │ │ │ │
|
||||
│ Element │ │ │ mx event │ │ │ │ Element │
|
||||
│ App │ │ │ └────────────────────┘ │ ┌────┐ │ App │
|
||||
│ │ │ ┌────────────────────┐ │ │ │ 3 │ │ │
|
||||
│ │◀──────────────────┼┐ │ │ m.call.answer │ │ ┌───────┴────┴────────│ │
|
||||
│ │ │ │ │ mx event │ │ ││ │ │
|
||||
└─────────────────┘ ││ │ └────────────────────┘ │ │ └─────────────────┘
|
||||
│ │ │ ┌────────────────────┐ │ ││ ▲
|
||||
│ │└─────────────────┼──│ m.call.candidates │ │ │ ├────┐
|
||||
▼ │ │ mx event │◀──┼────────────────┘│ │ 2 │
|
||||
┌─────────────────┐ │ │ └────────────────────┘ │ ┌────┴────┴───────┐
|
||||
│ │ └───────────────────────────┘ │ │ │
|
||||
│ │ │ │ │
|
||||
│ WebRtc │ │ │ WebRtc │
|
||||
│ │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ ┌───┴────────────────┐
|
||||
│ │ │ │ caller offer │
|
||||
┌────────┴───────────┐ │ │ └───┬────────────────┘
|
||||
│ callee answer ├─────┘ ┌───────────────┐ └─────────────────┘
|
||||
├────────────────────┤ │ Stun / Turn │ ▲
|
||||
│ callee ice │ ├───────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ┌────┐ │
|
||||
│ candidates │ │ │ 1 │ │
|
||||
└────────────────────┘ │ ├────┴──┴───────┐
|
||||
│ │ │
|
||||
│ │ Network Stack │
|
||||
│◀─────────────────────┤ │
|
||||
│ │ │
|
||||
│ └───────────────┘
|
||||
│
|
||||
─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ┘
|
||||
|
||||
|
||||
┌────┐
|
||||
│ 1 │ The WebRtc layer gathers information on how it can be reach by the other peer directly (Ice candidates)
|
||||
└────┘
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│candidate:1 1 tcp 1518149375 127.0.0.1 35990 typ host │
|
||||
└──────────────────────────────────────────────────────────────────┘
|
||||
┌──────────────────────────────────────────────────────────────────┐
|
||||
│candidate:2 1 UDP 2130706431 192.168.1.102 1816 typ host │
|
||||
└──────────────────────────────────────────────────────────────────┘
|
||||
|
||||
┌────┐
|
||||
│ 2 │ The WebRTC layer notifies the App layer when it finds new Ice Candidates
|
||||
└────┘
|
||||
|
||||
|
||||
|
||||
┌────┐ The app layer, takes the ice candidates, encapsulate them in one or several matrix event adds the callId and
|
||||
│ 3 │ send it to the other user via the room
|
||||
└────┘
|
||||
┌──────────────┐
|
||||
│ mx event │
|
||||
├──────────────┴────────────────────────┐
|
||||
│ type: m.call.candidates │
|
||||
│ │
|
||||
│ +CallId │
|
||||
│ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ice candidate sdp │ │
|
||||
│ └──────────────────┘ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ice candidate sdp │ │
|
||||
│ └──────────────────┘ │
|
||||
│ ┌──────────────────┐ │
|
||||
│ │ice candidate sdp │ │
|
||||
│ └──────────────────┘ │
|
||||
└───────────────────────────────────────┘
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
╔════════════════════════════════════════════════╗
|
||||
║ ║
|
||||
║D] Caller Callee connection ║
|
||||
║ ║
|
||||
╚════════════════════════════════════════════════╝
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
┌───────────────┐
|
||||
┌─────────────────┐ │ Matrix │ ┌─────────────────┐
|
||||
│ Caller │ ├───────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ Callee │
|
||||
└─────────────────┘ │ └─────────────────┘
|
||||
│
|
||||
│
|
||||
┌─────────────────┐ │ ┌─────────────────┐
|
||||
│ │ │ │ │
|
||||
│ │ │ │ │
|
||||
│ │ │ │ │
|
||||
│ Element │ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │ Element │
|
||||
│ App │ │ App │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
│ │ │ │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
┌───────────────┐
|
||||
│ Internet │
|
||||
├───────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
┌─────────────────┐ │ ┌─────────────────┐
|
||||
│ │ │ │ │
|
||||
│ ├───────────────────────────────────────────────────────────────────────────────────┴─────────────────────┤ │
|
||||
│ WebRtc │█████████████████████████████████████████████████████████████████████████████████████████████████████████│ WebRtc │
|
||||
┌─────────────┴──────┐ ├────────────────────────────────────────┬──────────────────────────┬───────────────┬─────────────────────┤ ┌─────┴──────────────┐
|
||||
│ callee answer │ │ │ │ Video / Audio Stream │ │ │ caller offer │
|
||||
├────────────────────┤ │ └──────────────────────────┘ │ │ ├────────────────────┤
|
||||
│ callee ice ├──────────┘ └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ └───────────┤ caller ice │
|
||||
│ candidates │ │ candidates │
|
||||
└────────────────────┘ └────────────────────┘
|
||||
|
||||
|
||||
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ │░
|
||||
│ If connection is impossible (firewall), and a turn │░
|
||||
│server is available, connection could happen through │░
|
||||
│ a relay │░
|
||||
│ │░
|
||||
└─────────────────────────────────────────────────────┘░
|
||||
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
||||
|
||||
|
||||
┌───────────────┐
|
||||
│ Internet │
|
||||
└─┬─────────────┴ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
||||
┌─────────────────┐ │ ┌─────────────────┐
|
||||
│ │ │ ┌─────────────────────────┐ │ │
|
||||
│ ├───────────────────────────────────────┐│ │ │ │ │
|
||||
│ WebRtc │███████████████████████████████████████││ │ │ WebRtc │
|
||||
│ ├───────────────────────────────────────┘│ │ │ │ │
|
||||
│ │ ┌────────┴─────────────────┐ │ Relay │┌─────────────────────────────────────┤ │
|
||||
┌───────────────┴────┐ │ │ Video / Audio Stream │ │ ││█████████████████████████████████████│ ┌───────┴────────────┐
|
||||
│ callee answer ├────────────┘ └────────┬─────────────────┘ │ │└─────────────────────────────────────┴─────────┤ caller offer │
|
||||
├────────────────────┤ │ │ │ ├────────────────────┤
|
||||
│ callee ice │ │ │ │ │ caller ice │
|
||||
│ candidates │ └─────────────────────────┘ │ │ candidates │
|
||||
└────────────────────┘ │ └────────────────────┘
|
||||
│
|
||||
│
|
||||
│
|
||||
│
|
||||
│
|
||||
└ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
|
@@ -1,2 +0,0 @@
|
||||
json_key_file("./fastlane/private/api-8525453667099313774-565354-aca0e6153603.json")
|
||||
package_name("im.vector.app")
|
@@ -1,60 +0,0 @@
|
||||
# This file contains the fastlane.tools configuration
|
||||
# You can find the documentation at https://docs.fastlane.tools
|
||||
#
|
||||
# For a list of all available actions, check out
|
||||
#
|
||||
# https://docs.fastlane.tools/actions
|
||||
#
|
||||
# For a list of all available plugins, check out
|
||||
#
|
||||
# https://docs.fastlane.tools/plugins/available-plugins
|
||||
#
|
||||
|
||||
# Uncomment the line if you want fastlane to automatically update itself
|
||||
# update_fastlane
|
||||
|
||||
default_platform(:android)
|
||||
|
||||
platform :android do
|
||||
desc "Runs all the tests"
|
||||
lane :test do
|
||||
gradle(task: "test")
|
||||
end
|
||||
|
||||
desc "Submit a new Beta Build to Crashlytics Beta"
|
||||
lane :beta do
|
||||
gradle(task: "clean assembleRelease")
|
||||
crashlytics
|
||||
|
||||
# sh "your_script.sh"
|
||||
# You can also use other beta testing services here
|
||||
end
|
||||
|
||||
desc "Deploy a new version to the Google Play"
|
||||
lane :deploy do
|
||||
gradle(task: "clean assembleRelease")
|
||||
upload_to_play_store
|
||||
end
|
||||
|
||||
desc "Deploy Google Play metadata"
|
||||
lane :deployMeta do
|
||||
# Doc: https://docs.fastlane.tools/actions/upload_to_play_store/
|
||||
upload_to_play_store(
|
||||
skip_upload_apk: true,
|
||||
skip_upload_aab: true,
|
||||
skip_upload_images: true,
|
||||
skip_upload_screenshots: true,
|
||||
skip_upload_changelogs: true,
|
||||
# Set to true to not update the PlayStore
|
||||
validate_only: false
|
||||
)
|
||||
end
|
||||
|
||||
desc "Get version code"
|
||||
lane :getVersionCode do
|
||||
versions = google_play_track_version_codes(track: "production")
|
||||
puts(versions)
|
||||
version_code = versions[0]
|
||||
puts(version_code)
|
||||
end
|
||||
end
|
@@ -1,64 +0,0 @@
|
||||
fastlane documentation
|
||||
----
|
||||
|
||||
# Installation
|
||||
|
||||
Make sure you have the latest version of the Xcode command line tools installed:
|
||||
|
||||
```sh
|
||||
xcode-select --install
|
||||
```
|
||||
|
||||
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
|
||||
|
||||
# Available Actions
|
||||
|
||||
## Android
|
||||
|
||||
### android test
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android test
|
||||
```
|
||||
|
||||
Runs all the tests
|
||||
|
||||
### android beta
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android beta
|
||||
```
|
||||
|
||||
Submit a new Beta Build to Crashlytics Beta
|
||||
|
||||
### android deploy
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android deploy
|
||||
```
|
||||
|
||||
Deploy a new version to the Google Play
|
||||
|
||||
### android deployMeta
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android deployMeta
|
||||
```
|
||||
|
||||
Deploy Google Play metadata
|
||||
|
||||
### android getVersionCode
|
||||
|
||||
```sh
|
||||
[bundle exec] fastlane android getVersionCode
|
||||
```
|
||||
|
||||
Get version code
|
||||
|
||||
----
|
||||
|
||||
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
|
||||
|
||||
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
|
||||
|
||||
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
|
@@ -1,2 +0,0 @@
|
||||
يحتوي هذا الإصدار الجديد بشكل أساسي على إصلاحات للأخطاء وتحسينات. إرسال الرسالة أصبح الآن أسرع بكثير.
|
||||
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.10
|
@@ -1,2 +0,0 @@
|
||||
يحتوي هذا الإصدار الجديد بشكل أساسي على تحسينات في واجهة المستخدم وتجربة المستخدم. يُمكنك الآن دعوة الأصدقاء وإنشاء رسالة مُباشرة بسرعة كبيرة عن طريق مسح رموز الاستجابة السريعة.
|
||||
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.11
|
@@ -1,2 +0,0 @@
|
||||
التغييرات الرئيسة في هذا الإصدار: مُعاينة URL، لوحة مفاتيح Emoji جديدة، إمكانيات جديدة لإعدادات الغرفة والثلج لميلاد المسيح!
|
||||
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.12
|
@@ -1,2 +0,0 @@
|
||||
التغييرات الرئيسة في هذا الإصدار: مُعاينة URL، لوحة مفاتيح Emoji جديدة، إمكانيات جديدة لإعدادات الغرفة والثلج لميلاد المسيح!
|
||||
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.13
|
@@ -1,2 +0,0 @@
|
||||
التغييرات الرئيسة في هذا الإصدار: تحرير أذونات الغُرفة، السِّمة التلقائية الفاتحة/الداكنة، ومجموعة من إصلاحات الأخطاء.
|
||||
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.14
|
@@ -1,2 +0,0 @@
|
||||
التغييرات الرئيسة في هذا الإصدار: دعم تسجيل الدخول الاجتماعي.
|
||||
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.15
|
@@ -1,2 +0,0 @@
|
||||
التغييرات الرئيسة في هذا الإصدار: دعم تسجيل الدخول الاجتماعي.
|
||||
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.15 and https://github.com/vector-im/element-android/releases/tag/v1.0.16
|
@@ -1,2 +0,0 @@
|
||||
التغييرات الرئيسة في هذا الإصدار: إصلاحات الأخطاء!
|
||||
سجل التعديل الكامل: https://github.com/vector-im/element-android/releases/tag/v1.0.17
|
@@ -1,2 +0,0 @@
|
||||
التغييرات الرئيسة في هذه النسخة: تحسينات على الأداء وإصلاح للعلل!
|
||||
اطّلع على سجل التغييرات الكامل هنا: https://github.com/vector-im/element-android/releases/tag/v1.1.1
|
@@ -1,31 +0,0 @@
|
||||
Element هو نوع جديد من تطبيقات المُراسلة والتعاون الذي:
|
||||
|
||||
1. يمنحك التحكم في المُحافضة على خصوصيتك
|
||||
2. يُتيح لك التواصل مع أي شخص على شبكة Matrix ، وحتى خارجها من خلال التكامل مع التطبيقات مثل Slack
|
||||
3. يحميك من الإعلانات والتنقيب عن البيانات وعمليات الحدائق المُسورة
|
||||
4. يؤمنك من خلال تعمية النهاية-إلى-النهاية، مع التوقيع المُتبادل للتحقق من الآخرين
|
||||
|
||||
يختلف Element تمامًا عن تطبيقات المُراسلة والتعاون الأُخرى لأنه لا مركزي ومفتوح المصدر.
|
||||
|
||||
يُتيح لك Element إمكانية الاستضافة الذاتية -أو اختيار مُضيف- بحيث تتمتع بالخصوصية والمُلكية والتحكم في بياناتك ومُحادثاتك. يُتيح لك الوصول إلى شبكة مفتوحة؛ لذلك لا يقتصر الأمر على التحدث إلى مستخدمي Element الآخرين فقط. كما انه آمن للغاية.
|
||||
|
||||
Element قادر على القيام بكل ذلك لأنه يعمل على Matrix -مِعيار التواصل المفتوح اللامركزي.
|
||||
|
||||
Element يمنحك زمام التحكم من خلال السماح لك باختيار من يستضيف المُحادثات الخاصة بك. من تطبيق Element، يُمكنك اختيار الاستضافة بطرق مختلفة:
|
||||
|
||||
1. الحُصول على حساب مجاني على الخادِم العام matrix.org الذي يستضيفه مطورو Matrix، أو اختر من بين آلاف الخوادِم العامة التي يستضيفها متطوعون
|
||||
2. استضافة حسابك بنفسك عن طريق تشغيل خادِم على أجهزتك الخاصة
|
||||
3. التسجيل للحصول على حساب على خادِم مُخصص بمُجرد الاشتراك في منصة استضافة Element Matrix Services
|
||||
|
||||
<b> لماذا تختار Element؟</b>
|
||||
|
||||
<b>تملَّك بياناتك</b>: أنت من تُقرر أين تحتفظ ببياناتك ورسائلك. أنت تمتلكها وتتحكم فيها، وليس بعض الشركات الكُبرى الإحتكارية التي تُنقِّب عن بياناتك أو تُتيح الوصول إلى أطراف ثالثة.
|
||||
|
||||
|
||||
<b>تراسُل وتعاون مفتوح</b>: يُمكنك مُحادثة أي شخص آخر على شبكة Matrix، سواء كانوا يستخدمون Element أو تطبيق Matrix آخر، وحتى إذا كانوا يستخدمون نظام مُراسلة مُختلف مثل Slack أو IRC أو XMPP.
|
||||
|
||||
<b>الأمان-الخارق</b>: تشفير حقيقي من النهاية إلى النهاية (فقط أطراف المُحادثة مَن يُمكنهم فك تشفير الرسائل)، والتوقيع المُتبادل للتحقق من أجهزة المُشاركين في المُحادثة.
|
||||
|
||||
<b>التواصل الكامل</b>: المُراسلة، المُكالمات الصوتية والمرئية، مُشاركة الملفات، مُشاركة الشاشة، مجموعة كاملة وكبيرة من عمليات التكامُل، الروبوتات والأدوات. بناء الغُرف، المُجتمعات، ابق على اتصال وأنجز المهام.
|
||||
|
||||
<b>أين ما كُنت</b>: ابق على اتصال أينما كنت مع سجل الرسائل المتزامن بالكامل عبر جميع أجهزتك وفي الويب على https://app.element.io.
|
@@ -1 +0,0 @@
|
||||
برنامج المراسلة الجماعية - الرسائل المشفرة والدردشة الجماعية ومكالمات الفيديو
|
@@ -1 +0,0 @@
|
||||
إيليمنت - تطبيق محادثات أمن
|
@@ -1,30 +0,0 @@
|
||||
Element е приложение от нов тип за съобщения и сътрудничество:
|
||||
|
||||
1. Дава Ви контрол, за да запазите поверителността си
|
||||
2. Позволява ви да комуникирате с всеки в мрежата на Matrix и дори извън него, като се интегрира с приложения като Slack
|
||||
3. Предпазва ви от реклами, изтичане на данни и търговско следене
|
||||
4. Защитава ви чрез шифроване от край до край, с кръстосано подписване, за да проверите другите
|
||||
|
||||
Element е напълно различен от другите приложения за съобщения и сътрудничество, понеже е децентрализиран и с отворен код.
|
||||
|
||||
Element ви позволява да го хоствате самостоятелно - или да изберете хост - така че да имате поверителност, собственост и контрол върху Вашите данни и разговори. Дава ви достъп до отворена мрежа, така че комуникацията Ви не е ограничена до потребителите на Element. И е много сигурно.
|
||||
|
||||
Element е в състояние да направи всичко това, защото работи върху Matrix - стандартът за отворена, децентрализирана комуникация.
|
||||
|
||||
Element ви дава контрол, като ви позволява да изберете кой да хоства Вашите разговори. От приложението Element можете да изберете хостване по различни начини:
|
||||
|
||||
1. Вземете безплатен профил на публичния сървър на matrix.org, хостван от разработчиците на Matrix, или изберете от хиляди публични сървъри, хоствани от доброволци
|
||||
2. Самостоятелно хоствайте профила си, като пуснете сървър на собствен хардуер
|
||||
3. Регистрирайте се за профил на персонализиран сървър, като се абонирате за хостинг платформата Element Matrix Services
|
||||
|
||||
<b>Защо да изберете Element?</b>
|
||||
|
||||
<b>ПРИТЕЖАВАЙТЕ ДАННИТЕ СИ</b>: Вие решавате къде да съхранявате вашите данни и съобщения. Вие ги притежавате и контролирате, а не някаква МЕГАКОРПОРАЦИЯ, която складира вашите данни или дава достъп на трети страни.
|
||||
|
||||
<b>ОТВОРЕНИ СЪОБЩЕНИЯ И СЪТРУДНИЧЕСТВО</b>: Можете да разговаряте с всеки друг в мрежата на Matrix, независимо дали използва Element или друго приложение на Matrix и дори ако използва различна система за съобщения като Slack, IRC or XMPP.
|
||||
|
||||
<b>СВРЪХ СИГУРНО</b>: Реално шифроване от край до край (само тези в разговора могат да дешифрират съобщения) и кръстосано подписване за проверка на устройствата на участниците в разговора.
|
||||
|
||||
<b>ПЪЛНА КОМУНИКАЦИЯ</b>: Съобщения, гласови и видео разговори, споделяне на файлове, споделяне на екран и цял куп интеграции, ботове и джаджи. Изграждайте стаи, общности, поддържайте връзка и направете нещата завършени.
|
||||
|
||||
<b>НАВСЯКЪДЕ КЪДЕТО СТЕ</b>: Поддържайте връзка, където и да сте, с напълно синхронизирана история на съобщенията на всичките ви устройства и чрез web на https://app.element.io.
|
@@ -1 +0,0 @@
|
||||
Сигурен децентрализиран чат и VoIP. Пазете данните си от външни лица.
|
@@ -1 +0,0 @@
|
||||
Element (предишен Riot.im)
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user