Merge develop into feature/fga/dagger_setup
This commit is contained in:
commit
4c88d8e3c2
214 changed files with 2662 additions and 1833 deletions
901
.editorconfig
Normal file
901
.editorconfig
Normal file
|
|
@ -0,0 +1,901 @@
|
|||
[*]
|
||||
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 = 4
|
||||
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
|
||||
|
||||
[*.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
|
||||
|
||||
[*.properties]
|
||||
ij_properties_align_group_field_declarations = false
|
||||
ij_properties_keep_blank_lines = false
|
||||
ij_properties_key_value_delimiter = equals
|
||||
ij_properties_spaces_around_key_value_delimiter = false
|
||||
|
||||
[.editorconfig]
|
||||
ij_editorconfig_align_group_field_declarations = false
|
||||
ij_editorconfig_space_after_colon = false
|
||||
ij_editorconfig_space_after_comma = true
|
||||
ij_editorconfig_space_before_colon = false
|
||||
ij_editorconfig_space_before_comma = false
|
||||
ij_editorconfig_spaces_around_assignment_operators = true
|
||||
|
||||
[{*.ant,*.fxml,*.jhm,*.jnlp,*.jrxml,*.rng,*.tld,*.wsdl,*.xml,*.xsd,*.xsl,*.xslt,*.xul}]
|
||||
ij_continuation_indent_size = 4
|
||||
ij_xml_align_attributes = false
|
||||
ij_xml_align_text = false
|
||||
ij_xml_attribute_wrap = normal
|
||||
ij_xml_block_comment_at_first_column = true
|
||||
ij_xml_keep_blank_lines = 2
|
||||
ij_xml_keep_indents_on_empty_lines = false
|
||||
ij_xml_keep_line_breaks = false
|
||||
ij_xml_keep_line_breaks_in_text = true
|
||||
ij_xml_keep_whitespaces = false
|
||||
ij_xml_keep_whitespaces_around_cdata = preserve
|
||||
ij_xml_keep_whitespaces_inside_cdata = false
|
||||
ij_xml_line_comment_at_first_column = true
|
||||
ij_xml_space_after_tag_name = false
|
||||
ij_xml_space_around_equals_in_attribute = false
|
||||
ij_xml_space_inside_empty_tag = true
|
||||
ij_xml_text_wrap = normal
|
||||
ij_xml_use_custom_settings = true
|
||||
|
||||
[{*.bash,*.sh,*.zsh}]
|
||||
indent_size = 2
|
||||
tab_width = 2
|
||||
ij_shell_binary_ops_start_line = false
|
||||
ij_shell_keep_column_alignment_padding = false
|
||||
ij_shell_minify_program = false
|
||||
ij_shell_redirect_followed_by_space = false
|
||||
ij_shell_switch_cases_indented = false
|
||||
ij_shell_use_unix_line_separator = true
|
||||
|
||||
[{*.c,*.c++,*.cc,*.cp,*.cpp,*.cu,*.cuh,*.cxx,*.h,*.h++,*.hh,*.hp,*.hpp,*.hxx,*.i,*.icc,*.ii,*.inl,*.ino,*.ipp,*.m,*.mm,*.pch,*.tcc,*.tpp}]
|
||||
ij_c_add_brief_tag = false
|
||||
ij_c_add_getter_prefix = true
|
||||
ij_c_add_setter_prefix = true
|
||||
ij_c_align_dictionary_pair_values = false
|
||||
ij_c_align_group_field_declarations = false
|
||||
ij_c_align_init_list_in_columns = true
|
||||
ij_c_align_multiline_array_initializer_expression = true
|
||||
ij_c_align_multiline_assignment = true
|
||||
ij_c_align_multiline_binary_operation = true
|
||||
ij_c_align_multiline_chained_methods = false
|
||||
ij_c_align_multiline_for = true
|
||||
ij_c_align_multiline_ternary_operation = true
|
||||
ij_c_array_initializer_comma_on_next_line = false
|
||||
ij_c_array_initializer_new_line_after_left_brace = false
|
||||
ij_c_array_initializer_right_brace_on_new_line = false
|
||||
ij_c_array_initializer_wrap = normal
|
||||
ij_c_assignment_wrap = off
|
||||
ij_c_binary_operation_sign_on_next_line = false
|
||||
ij_c_binary_operation_wrap = normal
|
||||
ij_c_blank_lines_after_class_header = 0
|
||||
ij_c_blank_lines_after_imports = 1
|
||||
ij_c_blank_lines_around_class = 1
|
||||
ij_c_blank_lines_around_field = 0
|
||||
ij_c_blank_lines_around_field_in_interface = 0
|
||||
ij_c_blank_lines_around_method = 1
|
||||
ij_c_blank_lines_around_method_in_interface = 1
|
||||
ij_c_blank_lines_around_namespace = 0
|
||||
ij_c_blank_lines_around_properties_in_declaration = 0
|
||||
ij_c_blank_lines_around_properties_in_interface = 0
|
||||
ij_c_blank_lines_before_imports = 1
|
||||
ij_c_blank_lines_before_method_body = 0
|
||||
ij_c_block_brace_placement = end_of_line
|
||||
ij_c_block_brace_style = end_of_line
|
||||
ij_c_block_comment_at_first_column = true
|
||||
ij_c_catch_on_new_line = false
|
||||
ij_c_class_brace_style = end_of_line
|
||||
ij_c_class_constructor_init_list_align_multiline = true
|
||||
ij_c_class_constructor_init_list_comma_on_next_line = false
|
||||
ij_c_class_constructor_init_list_new_line_after_colon = never
|
||||
ij_c_class_constructor_init_list_new_line_before_colon = if_long
|
||||
ij_c_class_constructor_init_list_wrap = normal
|
||||
ij_c_copy_is_deep = false
|
||||
ij_c_create_interface_for_categories = true
|
||||
ij_c_declare_generated_methods = true
|
||||
ij_c_description_include_member_names = true
|
||||
ij_c_discharged_short_ternary_operator = false
|
||||
ij_c_do_not_add_breaks = false
|
||||
ij_c_do_while_brace_force = never
|
||||
ij_c_else_on_new_line = false
|
||||
ij_c_enum_constants_comma_on_next_line = false
|
||||
ij_c_enum_constants_wrap = on_every_item
|
||||
ij_c_for_brace_force = never
|
||||
ij_c_for_statement_new_line_after_left_paren = false
|
||||
ij_c_for_statement_right_paren_on_new_line = false
|
||||
ij_c_for_statement_wrap = off
|
||||
ij_c_function_brace_placement = end_of_line
|
||||
ij_c_function_call_arguments_align_multiline = true
|
||||
ij_c_function_call_arguments_align_multiline_pars = false
|
||||
ij_c_function_call_arguments_comma_on_next_line = false
|
||||
ij_c_function_call_arguments_new_line_after_lpar = false
|
||||
ij_c_function_call_arguments_new_line_before_rpar = false
|
||||
ij_c_function_call_arguments_wrap = normal
|
||||
ij_c_function_non_top_after_return_type_wrap = normal
|
||||
ij_c_function_parameters_align_multiline = true
|
||||
ij_c_function_parameters_align_multiline_pars = false
|
||||
ij_c_function_parameters_comma_on_next_line = false
|
||||
ij_c_function_parameters_new_line_after_lpar = false
|
||||
ij_c_function_parameters_new_line_before_rpar = false
|
||||
ij_c_function_parameters_wrap = normal
|
||||
ij_c_function_top_after_return_type_wrap = normal
|
||||
ij_c_generate_additional_eq_operators = true
|
||||
ij_c_generate_additional_rel_operators = true
|
||||
ij_c_generate_class_constructor = true
|
||||
ij_c_generate_comparison_operators_use_std_tie = false
|
||||
ij_c_generate_instance_variables_for_properties = ask
|
||||
ij_c_generate_operators_as_members = true
|
||||
ij_c_header_guard_style_pattern = ${PROJECT_NAME}_${FILE_NAME}_${EXT}
|
||||
ij_c_if_brace_force = never
|
||||
ij_c_in_line_short_ternary_operator = true
|
||||
ij_c_indent_block_comment = true
|
||||
ij_c_indent_c_struct_members = 4
|
||||
ij_c_indent_case_from_switch = true
|
||||
ij_c_indent_class_members = 4
|
||||
ij_c_indent_directive_as_code = false
|
||||
ij_c_indent_implementation_members = 0
|
||||
ij_c_indent_inside_code_block = 4
|
||||
ij_c_indent_interface_members = 0
|
||||
ij_c_indent_interface_members_except_ivars_block = false
|
||||
ij_c_indent_namespace_members = 4
|
||||
ij_c_indent_preprocessor_directive = 0
|
||||
ij_c_indent_visibility_keywords = 0
|
||||
ij_c_insert_override = true
|
||||
ij_c_insert_virtual_with_override = false
|
||||
ij_c_introduce_auto_vars = false
|
||||
ij_c_introduce_const_params = false
|
||||
ij_c_introduce_const_vars = false
|
||||
ij_c_introduce_generate_property = false
|
||||
ij_c_introduce_generate_synthesize = true
|
||||
ij_c_introduce_globals_to_header = true
|
||||
ij_c_introduce_prop_to_private_category = false
|
||||
ij_c_introduce_static_consts = true
|
||||
ij_c_introduce_use_ns_types = false
|
||||
ij_c_ivars_prefix = _
|
||||
ij_c_keep_blank_lines_before_end = 2
|
||||
ij_c_keep_blank_lines_before_right_brace = 2
|
||||
ij_c_keep_blank_lines_in_code = 2
|
||||
ij_c_keep_blank_lines_in_declarations = 2
|
||||
ij_c_keep_case_expressions_in_one_line = false
|
||||
ij_c_keep_control_statement_in_one_line = true
|
||||
ij_c_keep_directive_at_first_column = true
|
||||
ij_c_keep_first_column_comment = true
|
||||
ij_c_keep_line_breaks = true
|
||||
ij_c_keep_nested_namespaces_in_one_line = false
|
||||
ij_c_keep_simple_blocks_in_one_line = true
|
||||
ij_c_keep_simple_methods_in_one_line = true
|
||||
ij_c_keep_structures_in_one_line = false
|
||||
ij_c_lambda_capture_list_align_multiline = false
|
||||
ij_c_lambda_capture_list_align_multiline_bracket = false
|
||||
ij_c_lambda_capture_list_comma_on_next_line = false
|
||||
ij_c_lambda_capture_list_new_line_after_lbracket = false
|
||||
ij_c_lambda_capture_list_new_line_before_rbracket = false
|
||||
ij_c_lambda_capture_list_wrap = off
|
||||
ij_c_line_comment_add_space = false
|
||||
ij_c_line_comment_at_first_column = true
|
||||
ij_c_method_brace_placement = end_of_line
|
||||
ij_c_method_call_arguments_align_by_colons = true
|
||||
ij_c_method_call_arguments_align_multiline = false
|
||||
ij_c_method_call_arguments_special_dictionary_pairs_treatment = true
|
||||
ij_c_method_call_arguments_wrap = off
|
||||
ij_c_method_call_chain_wrap = off
|
||||
ij_c_method_parameters_align_by_colons = true
|
||||
ij_c_method_parameters_align_multiline = false
|
||||
ij_c_method_parameters_wrap = off
|
||||
ij_c_namespace_brace_placement = end_of_line
|
||||
ij_c_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_c_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_c_place_assignment_sign_on_next_line = false
|
||||
ij_c_property_nonatomic = true
|
||||
ij_c_put_ivars_to_implementation = true
|
||||
ij_c_refactor_compatibility_aliases_and_classes = true
|
||||
ij_c_refactor_properties_and_ivars = true
|
||||
ij_c_release_style = ivar
|
||||
ij_c_retain_object_parameters_in_constructor = true
|
||||
ij_c_semicolon_after_method_signature = false
|
||||
ij_c_shift_operation_align_multiline = true
|
||||
ij_c_shift_operation_wrap = normal
|
||||
ij_c_show_non_virtual_functions = false
|
||||
ij_c_space_after_colon = true
|
||||
ij_c_space_after_colon_in_selector = false
|
||||
ij_c_space_after_comma = true
|
||||
ij_c_space_after_cup_in_blocks = false
|
||||
ij_c_space_after_dictionary_literal_colon = true
|
||||
ij_c_space_after_for_semicolon = true
|
||||
ij_c_space_after_init_list_colon = true
|
||||
ij_c_space_after_method_parameter_type_parentheses = false
|
||||
ij_c_space_after_method_return_type_parentheses = false
|
||||
ij_c_space_after_pointer_in_declaration = false
|
||||
ij_c_space_after_quest = true
|
||||
ij_c_space_after_reference_in_declaration = false
|
||||
ij_c_space_after_reference_in_rvalue = false
|
||||
ij_c_space_after_structures_rbrace = true
|
||||
ij_c_space_after_superclass_colon = true
|
||||
ij_c_space_after_type_cast = true
|
||||
ij_c_space_after_visibility_sign_in_method_declaration = true
|
||||
ij_c_space_before_autorelease_pool_lbrace = true
|
||||
ij_c_space_before_catch_keyword = true
|
||||
ij_c_space_before_catch_left_brace = true
|
||||
ij_c_space_before_catch_parentheses = true
|
||||
ij_c_space_before_category_parentheses = true
|
||||
ij_c_space_before_chained_send_message = true
|
||||
ij_c_space_before_class_left_brace = true
|
||||
ij_c_space_before_colon = true
|
||||
ij_c_space_before_comma = false
|
||||
ij_c_space_before_dictionary_literal_colon = false
|
||||
ij_c_space_before_do_left_brace = true
|
||||
ij_c_space_before_else_keyword = true
|
||||
ij_c_space_before_else_left_brace = true
|
||||
ij_c_space_before_for_left_brace = true
|
||||
ij_c_space_before_for_parentheses = true
|
||||
ij_c_space_before_for_semicolon = false
|
||||
ij_c_space_before_if_left_brace = true
|
||||
ij_c_space_before_if_parentheses = true
|
||||
ij_c_space_before_init_list = false
|
||||
ij_c_space_before_init_list_colon = true
|
||||
ij_c_space_before_method_call_parentheses = false
|
||||
ij_c_space_before_method_left_brace = true
|
||||
ij_c_space_before_method_parentheses = false
|
||||
ij_c_space_before_namespace_lbrace = true
|
||||
ij_c_space_before_pointer_in_declaration = true
|
||||
ij_c_space_before_property_attributes_parentheses = false
|
||||
ij_c_space_before_protocols_brackets = true
|
||||
ij_c_space_before_quest = true
|
||||
ij_c_space_before_reference_in_declaration = true
|
||||
ij_c_space_before_superclass_colon = true
|
||||
ij_c_space_before_switch_left_brace = true
|
||||
ij_c_space_before_switch_parentheses = true
|
||||
ij_c_space_before_template_call_lt = false
|
||||
ij_c_space_before_template_declaration_lt = false
|
||||
ij_c_space_before_try_left_brace = true
|
||||
ij_c_space_before_while_keyword = true
|
||||
ij_c_space_before_while_left_brace = true
|
||||
ij_c_space_before_while_parentheses = true
|
||||
ij_c_space_between_adjacent_brackets = false
|
||||
ij_c_space_between_operator_and_punctuator = false
|
||||
ij_c_space_within_empty_array_initializer_braces = false
|
||||
ij_c_spaces_around_additive_operators = true
|
||||
ij_c_spaces_around_assignment_operators = true
|
||||
ij_c_spaces_around_bitwise_operators = true
|
||||
ij_c_spaces_around_equality_operators = true
|
||||
ij_c_spaces_around_lambda_arrow = true
|
||||
ij_c_spaces_around_logical_operators = true
|
||||
ij_c_spaces_around_multiplicative_operators = true
|
||||
ij_c_spaces_around_pm_operators = false
|
||||
ij_c_spaces_around_relational_operators = true
|
||||
ij_c_spaces_around_shift_operators = true
|
||||
ij_c_spaces_around_unary_operator = false
|
||||
ij_c_spaces_within_array_initializer_braces = false
|
||||
ij_c_spaces_within_braces = true
|
||||
ij_c_spaces_within_brackets = false
|
||||
ij_c_spaces_within_cast_parentheses = false
|
||||
ij_c_spaces_within_catch_parentheses = false
|
||||
ij_c_spaces_within_category_parentheses = false
|
||||
ij_c_spaces_within_empty_braces = false
|
||||
ij_c_spaces_within_empty_function_call_parentheses = false
|
||||
ij_c_spaces_within_empty_function_declaration_parentheses = false
|
||||
ij_c_spaces_within_empty_lambda_capture_list_bracket = false
|
||||
ij_c_spaces_within_empty_template_call_ltgt = false
|
||||
ij_c_spaces_within_empty_template_declaration_ltgt = false
|
||||
ij_c_spaces_within_for_parentheses = false
|
||||
ij_c_spaces_within_function_call_parentheses = false
|
||||
ij_c_spaces_within_function_declaration_parentheses = false
|
||||
ij_c_spaces_within_if_parentheses = false
|
||||
ij_c_spaces_within_lambda_capture_list_bracket = false
|
||||
ij_c_spaces_within_method_parameter_type_parentheses = false
|
||||
ij_c_spaces_within_method_return_type_parentheses = false
|
||||
ij_c_spaces_within_parentheses = false
|
||||
ij_c_spaces_within_property_attributes_parentheses = false
|
||||
ij_c_spaces_within_protocols_brackets = false
|
||||
ij_c_spaces_within_send_message_brackets = false
|
||||
ij_c_spaces_within_switch_parentheses = false
|
||||
ij_c_spaces_within_template_call_ltgt = false
|
||||
ij_c_spaces_within_template_declaration_ltgt = false
|
||||
ij_c_spaces_within_template_double_gt = true
|
||||
ij_c_spaces_within_while_parentheses = false
|
||||
ij_c_special_else_if_treatment = true
|
||||
ij_c_superclass_list_after_colon = never
|
||||
ij_c_superclass_list_align_multiline = true
|
||||
ij_c_superclass_list_before_colon = if_long
|
||||
ij_c_superclass_list_comma_on_next_line = false
|
||||
ij_c_superclass_list_wrap = on_every_item
|
||||
ij_c_tag_prefix_of_block_comment = at
|
||||
ij_c_tag_prefix_of_line_comment = back_slash
|
||||
ij_c_template_call_arguments_align_multiline = false
|
||||
ij_c_template_call_arguments_align_multiline_pars = false
|
||||
ij_c_template_call_arguments_comma_on_next_line = false
|
||||
ij_c_template_call_arguments_new_line_after_lt = false
|
||||
ij_c_template_call_arguments_new_line_before_gt = false
|
||||
ij_c_template_call_arguments_wrap = off
|
||||
ij_c_template_declaration_function_body_indent = false
|
||||
ij_c_template_declaration_function_wrap = split_into_lines
|
||||
ij_c_template_declaration_struct_body_indent = false
|
||||
ij_c_template_declaration_struct_wrap = split_into_lines
|
||||
ij_c_template_parameters_align_multiline = false
|
||||
ij_c_template_parameters_align_multiline_pars = false
|
||||
ij_c_template_parameters_comma_on_next_line = false
|
||||
ij_c_template_parameters_new_line_after_lt = false
|
||||
ij_c_template_parameters_new_line_before_gt = false
|
||||
ij_c_template_parameters_wrap = off
|
||||
ij_c_ternary_operation_signs_on_next_line = true
|
||||
ij_c_ternary_operation_wrap = normal
|
||||
ij_c_type_qualifiers_placement = before
|
||||
ij_c_use_modern_casts = true
|
||||
ij_c_use_setters_in_constructor = true
|
||||
ij_c_while_brace_force = never
|
||||
ij_c_while_on_new_line = false
|
||||
ij_c_wrap_property_declaration = off
|
||||
|
||||
[{*.cmake,CMakeLists.txt}]
|
||||
ij_cmake_align_multiline_parameters_in_calls = false
|
||||
ij_cmake_force_commands_case = 2
|
||||
ij_cmake_keep_blank_lines_in_code = 2
|
||||
ij_cmake_space_before_for_parentheses = true
|
||||
ij_cmake_space_before_if_parentheses = true
|
||||
ij_cmake_space_before_method_call_parentheses = false
|
||||
ij_cmake_space_before_method_parentheses = false
|
||||
ij_cmake_space_before_while_parentheses = true
|
||||
ij_cmake_spaces_within_for_parentheses = false
|
||||
ij_cmake_spaces_within_if_parentheses = false
|
||||
ij_cmake_spaces_within_method_call_parentheses = false
|
||||
ij_cmake_spaces_within_method_parentheses = false
|
||||
ij_cmake_spaces_within_while_parentheses = false
|
||||
|
||||
[{*.gant,*.gradle,*.groovy,*.gy}]
|
||||
ij_groovy_align_group_field_declarations = false
|
||||
ij_groovy_align_multiline_array_initializer_expression = false
|
||||
ij_groovy_align_multiline_assignment = false
|
||||
ij_groovy_align_multiline_binary_operation = false
|
||||
ij_groovy_align_multiline_chained_methods = false
|
||||
ij_groovy_align_multiline_extends_list = false
|
||||
ij_groovy_align_multiline_for = true
|
||||
ij_groovy_align_multiline_list_or_map = true
|
||||
ij_groovy_align_multiline_method_parentheses = false
|
||||
ij_groovy_align_multiline_parameters = true
|
||||
ij_groovy_align_multiline_parameters_in_calls = false
|
||||
ij_groovy_align_multiline_resources = true
|
||||
ij_groovy_align_multiline_ternary_operation = false
|
||||
ij_groovy_align_multiline_throws_list = false
|
||||
ij_groovy_align_named_args_in_map = true
|
||||
ij_groovy_align_throws_keyword = false
|
||||
ij_groovy_array_initializer_new_line_after_left_brace = false
|
||||
ij_groovy_array_initializer_right_brace_on_new_line = false
|
||||
ij_groovy_array_initializer_wrap = off
|
||||
ij_groovy_assert_statement_wrap = off
|
||||
ij_groovy_assignment_wrap = off
|
||||
ij_groovy_binary_operation_wrap = off
|
||||
ij_groovy_blank_lines_after_class_header = 0
|
||||
ij_groovy_blank_lines_after_imports = 1
|
||||
ij_groovy_blank_lines_after_package = 1
|
||||
ij_groovy_blank_lines_around_class = 1
|
||||
ij_groovy_blank_lines_around_field = 0
|
||||
ij_groovy_blank_lines_around_field_in_interface = 0
|
||||
ij_groovy_blank_lines_around_method = 1
|
||||
ij_groovy_blank_lines_around_method_in_interface = 1
|
||||
ij_groovy_blank_lines_before_imports = 1
|
||||
ij_groovy_blank_lines_before_method_body = 0
|
||||
ij_groovy_blank_lines_before_package = 0
|
||||
ij_groovy_block_brace_style = end_of_line
|
||||
ij_groovy_block_comment_at_first_column = true
|
||||
ij_groovy_call_parameters_new_line_after_left_paren = false
|
||||
ij_groovy_call_parameters_right_paren_on_new_line = false
|
||||
ij_groovy_call_parameters_wrap = off
|
||||
ij_groovy_catch_on_new_line = false
|
||||
ij_groovy_class_annotation_wrap = split_into_lines
|
||||
ij_groovy_class_brace_style = end_of_line
|
||||
ij_groovy_class_count_to_use_import_on_demand = 5
|
||||
ij_groovy_do_while_brace_force = never
|
||||
ij_groovy_else_on_new_line = false
|
||||
ij_groovy_enum_constants_wrap = off
|
||||
ij_groovy_extends_keyword_wrap = off
|
||||
ij_groovy_extends_list_wrap = off
|
||||
ij_groovy_field_annotation_wrap = split_into_lines
|
||||
ij_groovy_finally_on_new_line = false
|
||||
ij_groovy_for_brace_force = never
|
||||
ij_groovy_for_statement_new_line_after_left_paren = false
|
||||
ij_groovy_for_statement_right_paren_on_new_line = false
|
||||
ij_groovy_for_statement_wrap = off
|
||||
ij_groovy_if_brace_force = never
|
||||
ij_groovy_import_annotation_wrap = 2
|
||||
ij_groovy_imports_layout = *, |, javax.**, java.**, |, $*
|
||||
ij_groovy_indent_case_from_switch = true
|
||||
ij_groovy_indent_label_blocks = true
|
||||
ij_groovy_insert_inner_class_imports = false
|
||||
ij_groovy_keep_blank_lines_before_right_brace = 2
|
||||
ij_groovy_keep_blank_lines_in_code = 2
|
||||
ij_groovy_keep_blank_lines_in_declarations = 2
|
||||
ij_groovy_keep_control_statement_in_one_line = true
|
||||
ij_groovy_keep_first_column_comment = true
|
||||
ij_groovy_keep_indents_on_empty_lines = false
|
||||
ij_groovy_keep_line_breaks = true
|
||||
ij_groovy_keep_multiple_expressions_in_one_line = false
|
||||
ij_groovy_keep_simple_blocks_in_one_line = false
|
||||
ij_groovy_keep_simple_classes_in_one_line = true
|
||||
ij_groovy_keep_simple_lambdas_in_one_line = true
|
||||
ij_groovy_keep_simple_methods_in_one_line = true
|
||||
ij_groovy_label_indent_absolute = false
|
||||
ij_groovy_label_indent_size = 0
|
||||
ij_groovy_lambda_brace_style = end_of_line
|
||||
ij_groovy_layout_static_imports_separately = true
|
||||
ij_groovy_line_comment_add_space = false
|
||||
ij_groovy_line_comment_at_first_column = true
|
||||
ij_groovy_method_annotation_wrap = split_into_lines
|
||||
ij_groovy_method_brace_style = end_of_line
|
||||
ij_groovy_method_call_chain_wrap = off
|
||||
ij_groovy_method_parameters_new_line_after_left_paren = false
|
||||
ij_groovy_method_parameters_right_paren_on_new_line = false
|
||||
ij_groovy_method_parameters_wrap = off
|
||||
ij_groovy_modifier_list_wrap = false
|
||||
ij_groovy_names_count_to_use_import_on_demand = 3
|
||||
ij_groovy_parameter_annotation_wrap = off
|
||||
ij_groovy_parentheses_expression_new_line_after_left_paren = false
|
||||
ij_groovy_parentheses_expression_right_paren_on_new_line = false
|
||||
ij_groovy_prefer_parameters_wrap = false
|
||||
ij_groovy_resource_list_new_line_after_left_paren = false
|
||||
ij_groovy_resource_list_right_paren_on_new_line = false
|
||||
ij_groovy_resource_list_wrap = off
|
||||
ij_groovy_space_after_assert_separator = true
|
||||
ij_groovy_space_after_colon = true
|
||||
ij_groovy_space_after_comma = true
|
||||
ij_groovy_space_after_comma_in_type_arguments = true
|
||||
ij_groovy_space_after_for_semicolon = true
|
||||
ij_groovy_space_after_quest = true
|
||||
ij_groovy_space_after_type_cast = true
|
||||
ij_groovy_space_before_annotation_parameter_list = false
|
||||
ij_groovy_space_before_array_initializer_left_brace = false
|
||||
ij_groovy_space_before_assert_separator = false
|
||||
ij_groovy_space_before_catch_keyword = true
|
||||
ij_groovy_space_before_catch_left_brace = true
|
||||
ij_groovy_space_before_catch_parentheses = true
|
||||
ij_groovy_space_before_class_left_brace = true
|
||||
ij_groovy_space_before_closure_left_brace = true
|
||||
ij_groovy_space_before_colon = true
|
||||
ij_groovy_space_before_comma = false
|
||||
ij_groovy_space_before_do_left_brace = true
|
||||
ij_groovy_space_before_else_keyword = true
|
||||
ij_groovy_space_before_else_left_brace = true
|
||||
ij_groovy_space_before_finally_keyword = true
|
||||
ij_groovy_space_before_finally_left_brace = true
|
||||
ij_groovy_space_before_for_left_brace = true
|
||||
ij_groovy_space_before_for_parentheses = true
|
||||
ij_groovy_space_before_for_semicolon = false
|
||||
ij_groovy_space_before_if_left_brace = true
|
||||
ij_groovy_space_before_if_parentheses = true
|
||||
ij_groovy_space_before_method_call_parentheses = false
|
||||
ij_groovy_space_before_method_left_brace = true
|
||||
ij_groovy_space_before_method_parentheses = false
|
||||
ij_groovy_space_before_quest = true
|
||||
ij_groovy_space_before_switch_left_brace = true
|
||||
ij_groovy_space_before_switch_parentheses = true
|
||||
ij_groovy_space_before_synchronized_left_brace = true
|
||||
ij_groovy_space_before_synchronized_parentheses = true
|
||||
ij_groovy_space_before_try_left_brace = true
|
||||
ij_groovy_space_before_try_parentheses = true
|
||||
ij_groovy_space_before_while_keyword = true
|
||||
ij_groovy_space_before_while_left_brace = true
|
||||
ij_groovy_space_before_while_parentheses = true
|
||||
ij_groovy_space_in_named_argument = true
|
||||
ij_groovy_space_in_named_argument_before_colon = false
|
||||
ij_groovy_space_within_empty_array_initializer_braces = false
|
||||
ij_groovy_space_within_empty_method_call_parentheses = false
|
||||
ij_groovy_spaces_around_additive_operators = true
|
||||
ij_groovy_spaces_around_assignment_operators = true
|
||||
ij_groovy_spaces_around_bitwise_operators = true
|
||||
ij_groovy_spaces_around_equality_operators = true
|
||||
ij_groovy_spaces_around_lambda_arrow = true
|
||||
ij_groovy_spaces_around_logical_operators = true
|
||||
ij_groovy_spaces_around_multiplicative_operators = true
|
||||
ij_groovy_spaces_around_regex_operators = true
|
||||
ij_groovy_spaces_around_relational_operators = true
|
||||
ij_groovy_spaces_around_shift_operators = true
|
||||
ij_groovy_spaces_within_annotation_parentheses = false
|
||||
ij_groovy_spaces_within_array_initializer_braces = false
|
||||
ij_groovy_spaces_within_braces = true
|
||||
ij_groovy_spaces_within_brackets = false
|
||||
ij_groovy_spaces_within_cast_parentheses = false
|
||||
ij_groovy_spaces_within_catch_parentheses = false
|
||||
ij_groovy_spaces_within_for_parentheses = false
|
||||
ij_groovy_spaces_within_gstring_injection_braces = false
|
||||
ij_groovy_spaces_within_if_parentheses = false
|
||||
ij_groovy_spaces_within_list_or_map = false
|
||||
ij_groovy_spaces_within_method_call_parentheses = false
|
||||
ij_groovy_spaces_within_method_parentheses = false
|
||||
ij_groovy_spaces_within_parentheses = false
|
||||
ij_groovy_spaces_within_switch_parentheses = false
|
||||
ij_groovy_spaces_within_synchronized_parentheses = false
|
||||
ij_groovy_spaces_within_try_parentheses = false
|
||||
ij_groovy_spaces_within_tuple_expression = false
|
||||
ij_groovy_spaces_within_while_parentheses = false
|
||||
ij_groovy_special_else_if_treatment = true
|
||||
ij_groovy_ternary_operation_wrap = off
|
||||
ij_groovy_throws_keyword_wrap = off
|
||||
ij_groovy_throws_list_wrap = off
|
||||
ij_groovy_use_flying_geese_braces = false
|
||||
ij_groovy_use_fq_class_names = false
|
||||
ij_groovy_use_fq_class_names_in_javadoc = true
|
||||
ij_groovy_use_relative_indents = false
|
||||
ij_groovy_use_single_class_imports = true
|
||||
ij_groovy_variable_annotation_wrap = off
|
||||
ij_groovy_while_brace_force = never
|
||||
ij_groovy_while_on_new_line = false
|
||||
ij_groovy_wrap_long_lines = false
|
||||
|
||||
[{*.gradle.kts,*.kt,*.kts,*.main.kts}]
|
||||
ij_kotlin_align_in_columns_case_branch = 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
|
||||
33
.github/workflows/build.yml
vendored
Normal file
33
.github/workflows/build.yml
vendored
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
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
|
||||
runs-on: ubuntu-latest
|
||||
if: github.ref != 'refs/heads/main'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
# Allow all jobs on develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/develop' && format('build-develop-{0}', github.sha) || format('build-debug-{0}', github.ref) }}
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Assemble debug APK
|
||||
run: ./gradlew assembleDebug $CI_GRADLE_ARG_PROPERTIES
|
||||
- name: Upload debug APKs
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: elementx-debug
|
||||
path: |
|
||||
app/build/outputs/apk/debug/app-debug.apk
|
||||
20
.github/workflows/danger.yml
vendored
Normal file
20
.github/workflows/danger.yml
vendored
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
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.2.0
|
||||
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/dependabot.yml
vendored
Normal file
22
.github/workflows/dependabot.yml
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# 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://docs.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: "daily"
|
||||
reviewers:
|
||||
- "vector-im/element-x-android-reviewers"
|
||||
# Updates for Gradle dependencies used in the app
|
||||
- package-ecosystem: "gradle"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "daily"
|
||||
open-pull-requests-limit: 200
|
||||
reviewers:
|
||||
- "vector-im/element-x-android-reviewers"
|
||||
46
.github/workflows/quality.yml
vendored
Normal file
46
.github/workflows/quality.yml
vendored
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
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
|
||||
# Allow all jobs on main and develop. Just one per PR.
|
||||
concurrency:
|
||||
group: ${{ github.ref == 'refs/heads/main' && format('check-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-develop-{0}', github.sha) || format('check-{0}', github.ref) }}
|
||||
cancel-in-progress: true
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run code quality check suite
|
||||
run: ./gradlew check $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.2.0
|
||||
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 }}
|
||||
25
.github/workflows/tests.yml
vendored
Normal file
25
.github/workflows/tests.yml
vendored
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
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 4 --no-daemon
|
||||
|
||||
jobs:
|
||||
tests:
|
||||
name: Runs unit tests
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
# 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
|
||||
- name: Run tests
|
||||
run: ./gradlew test $CI_GRADLE_ARG_PROPERTIES
|
||||
2
.github/workflows/triage-labelled.yml
vendored
2
.github/workflows/triage-labelled.yml
vendored
|
|
@ -2,7 +2,7 @@ name: Move labelled issues to correct boards and columns
|
|||
|
||||
on:
|
||||
issues:
|
||||
types: [labeled]
|
||||
types: [ labeled ]
|
||||
|
||||
jobs:
|
||||
move_element_x_issues:
|
||||
|
|
|
|||
125
.idea/codeStyles/Project.xml
generated
Normal file
125
.idea/codeStyles/Project.xml
generated
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<JetCodeStyleSettings>
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="2147483647" />
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="2147483647" />
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</JetCodeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
generated
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
|
||||
</state>
|
||||
</component>
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
# element-x-android-poc
|
||||
|
||||
Proof Of Concept to run a Matrix client on Android devices using the Matrix Rust Sdk and Jetpack compose.
|
||||
|
||||
The plan is [here](https://github.com/vector-im/element-x-android-poc/issues/1)!
|
||||
The plan is [here](https://github.com/vector-im/element-x-android-poc/issues/1)!
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ plugins {
|
|||
alias(libs.plugins.anvil)
|
||||
alias(libs.plugins.kapt)
|
||||
id("com.google.firebase.appdistribution") version "3.0.2"
|
||||
id("org.jetbrains.kotlinx.knit") version "0.4.0"
|
||||
}
|
||||
|
||||
android {
|
||||
|
|
@ -12,7 +13,7 @@ android {
|
|||
|
||||
defaultConfig {
|
||||
applicationId = "io.element.android.x"
|
||||
targetSdk = 33
|
||||
targetSdk = 33 // TODO Use Versions.targetSdk
|
||||
versionCode = 1
|
||||
versionName = "1.0"
|
||||
|
||||
|
|
@ -81,7 +82,6 @@ android {
|
|||
appId = "1:912726360885:android:e17435e0beb0303000427c"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
|
|
@ -111,6 +111,26 @@ android {
|
|||
}
|
||||
}
|
||||
|
||||
// Knit
|
||||
apply {
|
||||
plugin("kotlinx-knit")
|
||||
}
|
||||
|
||||
knit {
|
||||
files = fileTree(project.rootDir) {
|
||||
include(
|
||||
"**/*.md",
|
||||
"**/*.kt",
|
||||
"*/*.kts",
|
||||
)
|
||||
exclude(
|
||||
"**/build/**",
|
||||
"*/.gradle/**",
|
||||
"*/towncrier/template.md",
|
||||
"**/CHANGES.md",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(project(":libraries:designsystem"))
|
||||
|
|
@ -134,7 +154,6 @@ dependencies {
|
|||
implementation(libs.androidx.activity.compose)
|
||||
implementation(libs.androidx.startup)
|
||||
implementation(libs.coil)
|
||||
implementation(libs.timber)
|
||||
implementation(libs.mavericks.compose)
|
||||
|
||||
implementation(libs.dagger)
|
||||
|
|
@ -142,4 +161,4 @@ dependencies {
|
|||
|
||||
implementation(libs.showkase)
|
||||
ksp(libs.showkase.processor)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ import com.airbnb.android.showkase.annotation.ShowkaseRoot
|
|||
import com.airbnb.android.showkase.annotation.ShowkaseRootModule
|
||||
|
||||
@ShowkaseRoot
|
||||
class ElementRootModule : ShowkaseRootModule
|
||||
class ElementRootModule : ShowkaseRootModule
|
||||
|
|
@ -30,6 +30,4 @@ class ElementXApplication : Application(), DaggerComponentOwner {
|
|||
initializeComponent(MavericksInitializer::class.java)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,8 +19,17 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
|
@ -109,7 +118,6 @@ class MainActivity : ComponentActivity() {
|
|||
OnLifecycleEvent { _, event ->
|
||||
Timber.v("OnLifecycleEvent: $event")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -171,5 +179,4 @@ class MainActivity : ComponentActivity() {
|
|||
fun MainContentPreview() {
|
||||
MainContent(startRoute = OnBoardingScreenNavigationDestination)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -50,4 +50,4 @@ class MainViewModel @AssistedInject constructor(
|
|||
matrixClient.startSync()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,11 @@ import com.ramcosta.composedestinations.annotation.RootNavGraph
|
|||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||
import com.ramcosta.composedestinations.navigation.popUpTo
|
||||
import io.element.android.x.core.di.bindings
|
||||
import io.element.android.x.destinations.*
|
||||
import io.element.android.x.destinations.ChangeServerScreenNavigationDestination
|
||||
import io.element.android.x.destinations.LoginScreenNavigationDestination
|
||||
import io.element.android.x.destinations.MessagesScreenNavigationDestination
|
||||
import io.element.android.x.destinations.OnBoardingScreenNavigationDestination
|
||||
import io.element.android.x.destinations.RoomListScreenNavigationDestination
|
||||
import io.element.android.x.di.AppBindings
|
||||
import io.element.android.x.features.login.LoginScreen
|
||||
import io.element.android.x.features.login.changeserver.ChangeServerScreen
|
||||
|
|
@ -84,6 +88,3 @@ fun RoomListScreenNavigation(navigator: DestinationsNavigator) {
|
|||
fun MessagesScreenNavigation(roomId: String, navigator: DestinationsNavigator) {
|
||||
MessagesScreen(roomId = roomId, onBackPressed = navigator::navigateUp)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,170 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
||||
|
|
@ -1,27 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<group android:scaleX="0.675"
|
||||
android:scaleY="0.675"
|
||||
android:translateX="32.4"
|
||||
android:translateY="32.4">
|
||||
<path
|
||||
android:pathData="M23.04,3.84C23.04,1.7192 24.7593,0 26.88,0C41.0185,0 52.48,11.4615 52.48,25.6C52.48,27.7208 50.7608,29.44 48.64,29.44C46.5193,29.44 44.8,27.7208 44.8,25.6C44.8,15.7031 36.777,7.68 26.88,7.68C24.7593,7.68 23.04,5.9608 23.04,3.84Z"
|
||||
android:fillColor="#FFF"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M40.96,60.16C40.96,62.2808 39.2407,64 37.12,64C22.9815,64 11.52,52.5385 11.52,38.4C11.52,36.2792 13.2392,34.56 15.36,34.56C17.4807,34.56 19.2,36.2792 19.2,38.4C19.2,48.2969 27.223,56.32 37.12,56.32C39.2407,56.32 40.96,58.0392 40.96,60.16Z"
|
||||
android:fillColor="#FFF"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M3.84,40.96C1.7192,40.96 -0,39.2407 -0,37.12C-0,22.9815 11.4615,11.52 25.6,11.52C27.7208,11.52 29.44,13.2392 29.44,15.36C29.44,17.4807 27.7208,19.2 25.6,19.2C15.7031,19.2 7.68,27.223 7.68,37.12C7.68,39.2407 5.9608,40.96 3.84,40.96Z"
|
||||
android:fillColor="#FFF"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M60.16,23.04C62.2808,23.04 64,24.7593 64,26.88C64,41.0185 52.5385,52.48 38.4,52.48C36.2792,52.48 34.56,50.7608 34.56,48.64C34.56,46.5193 36.2792,44.8 38.4,44.8C48.2969,44.8 56.32,36.777 56.32,26.88C56.32,24.7593 58.0392,23.04 60.16,23.04Z"
|
||||
android:fillColor="#FFF"
|
||||
android:fillType="evenOdd"/>
|
||||
</group>
|
||||
</vector>
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_launcher_background">#000000</color>
|
||||
</resources>
|
||||
|
|
@ -7,8 +7,78 @@ plugins {
|
|||
alias(libs.plugins.anvil) apply false
|
||||
alias(libs.plugins.kotlin.jvm) apply false
|
||||
alias(libs.plugins.kapt) apply false
|
||||
alias(libs.plugins.detekt)
|
||||
alias(libs.plugins.ktlint)
|
||||
}
|
||||
|
||||
tasks.register<Delete>("clean").configure {
|
||||
delete(rootProject.buildDir)
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
// Detekt
|
||||
apply {
|
||||
plugin("io.gitlab.arturbosch.detekt")
|
||||
}
|
||||
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")
|
||||
}
|
||||
dependencies {
|
||||
detektPlugins("com.twitter.compose.rules:detekt:0.0.26")
|
||||
}
|
||||
|
||||
// KtLint
|
||||
apply {
|
||||
plugin("org.jlleitschuh.gradle.ktlint")
|
||||
}
|
||||
|
||||
// See https://github.com/JLLeitschuh/ktlint-gradle#configuration
|
||||
configure<org.jlleitschuh.gradle.ktlint.KtlintExtension> {
|
||||
// See https://github.com/pinterest/ktlint/releases/
|
||||
// TODO 0.47.1 is available
|
||||
version.set("0.45.1")
|
||||
android.set(true)
|
||||
ignoreFailures.set(false)
|
||||
enableExperimentalRules.set(true)
|
||||
// display the corresponding rule
|
||||
verbose.set(true)
|
||||
reporters {
|
||||
reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.PLAIN)
|
||||
// To have XML report for Danger
|
||||
reporter(org.jlleitschuh.gradle.ktlint.reporter.ReporterType.CHECKSTYLE)
|
||||
}
|
||||
filter {
|
||||
exclude { element -> element.file.path.contains("$buildDir/generated/") }
|
||||
}
|
||||
disabledRules.set(
|
||||
setOf(
|
||||
// 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",
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,22 @@
|
|||
<!--- TOC -->
|
||||
|
||||
* [VersionCatalog](#versioncatalog)
|
||||
* [Jetpack Compose](#jetpack-compose)
|
||||
|
||||
<!--- END -->
|
||||
|
||||
### VersionCatalog
|
||||
|
||||
|
||||
|
||||
https://docs.gradle.org/current/userguide/platforms.html
|
||||
|
||||
### Jetpack Compose
|
||||
|
||||
https://developer.android.com/jetpack/compose/mental-model
|
||||
|
||||
https://developer.android.com/jetpack/compose/libraries
|
||||
https://developer.android.com/jetpack/compose/modifiers-list
|
||||
|
||||
https://android.googlesource.com/platform/frameworks/support/+/androidx-main/compose/docs/compose-api-guidelines.md#api-guidelines-for-jetpack-compose
|
||||
|
||||
Preview
|
||||
https://alexzh.com/jetpack-compose-preview/
|
||||
https://github.com/airbnb/Showkase
|
||||
https://github.com/airbnb/Showkase
|
||||
|
|
|
|||
|
|
@ -23,8 +23,6 @@ dependencies {
|
|||
implementation(project(":libraries:elementresources"))
|
||||
implementation(libs.mavericks.compose)
|
||||
ksp(libs.showkase.processor)
|
||||
implementation(libs.timber)
|
||||
testImplementation(libs.test.junit)
|
||||
androidTestImplementation(libs.test.junitext)
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
package io.element.android.x.features.login
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
|
|
@ -21,4 +19,4 @@ class ExampleInstrumentedTest {
|
|||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("io.element.android.x.features.login.test", appContext.packageName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,13 @@
|
|||
|
||||
package io.element.android.x.features.login
|
||||
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
|
|
@ -10,8 +16,21 @@ import androidx.compose.foundation.verticalScroll
|
|||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Visibility
|
||||
import androidx.compose.material.icons.filled.VisibilityOff
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
|
|
@ -56,19 +75,22 @@ fun LoginScreen(
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun LoginContent(
|
||||
state: LoginViewState,
|
||||
formState: LoginFormState,
|
||||
modifier: Modifier = Modifier,
|
||||
onChangeServer: () -> Unit = {},
|
||||
onLoginChanged: (String) -> Unit = {},
|
||||
onPasswordChanged: (String) -> Unit = {},
|
||||
onSubmitClicked: () -> Unit = {},
|
||||
onLoginWithSuccess: (MatrixClient) -> Unit = {},
|
||||
) {
|
||||
Surface(color = MaterialTheme.colorScheme.background) {
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
color = MaterialTheme.colorScheme.background,
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
|
|
@ -96,7 +118,7 @@ fun LoginContent(
|
|||
)
|
||||
// Form
|
||||
Column(
|
||||
//modifier = Modifier.weight(1f),
|
||||
// modifier = Modifier.weight(1f),
|
||||
) {
|
||||
Box(
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
|
|
|
|||
|
|
@ -66,4 +66,4 @@ class LoginViewModel @AssistedInject constructor(
|
|||
formState.value = formState.value.copy(login = name)
|
||||
setState { copy(loggedInClient = Uninitialized) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,5 +23,4 @@ data class LoginFormState(
|
|||
companion object {
|
||||
val Default = LoginFormState("", "")
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,27 @@
|
|||
package io.element.android.x.features.login.changeserver
|
||||
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.defaultMinSize
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.Alignment
|
||||
|
|
@ -45,15 +59,18 @@ fun ChangeServerScreen(
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun ChangeServerContent(
|
||||
state: ChangeServerViewState,
|
||||
modifier: Modifier = Modifier,
|
||||
onChangeServer: (String) -> Unit = {},
|
||||
onChangeServerSubmit: () -> Unit = {},
|
||||
onChangeServerSuccess: () -> Unit = {},
|
||||
) {
|
||||
Surface(color = MaterialTheme.colorScheme.background) {
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
color = MaterialTheme.colorScheme.background,
|
||||
) {
|
||||
val scrollState = rememberScrollState()
|
||||
Box(
|
||||
modifier = Modifier
|
||||
|
|
@ -67,8 +84,7 @@ fun ChangeServerContent(
|
|||
state = scrollState,
|
||||
)
|
||||
.padding(horizontal = 16.dp)
|
||||
)
|
||||
{
|
||||
) {
|
||||
val isError = state.changeServerAction is Fail
|
||||
Box(
|
||||
modifier = Modifier
|
||||
|
|
@ -101,7 +117,7 @@ fun ChangeServerContent(
|
|||
)
|
||||
Text(
|
||||
text = "A server is a home for all your data.\n" +
|
||||
"You choose your server and it’s easy to make one.", // TODO "Learn more.",
|
||||
"You choose your server and it’s easy to make one.", // TODO "Learn more.",
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.align(Alignment.CenterHorizontally)
|
||||
|
|
|
|||
|
|
@ -48,4 +48,4 @@ class ChangeServerViewModel @AssistedInject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,4 +10,4 @@ data class ChangeServerViewState(
|
|||
val changeServerAction: Async<Unit> = Uninitialized,
|
||||
) : MavericksState {
|
||||
val submitEnabled = homeserver.isNotEmpty() && changeServerAction !is Loading
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ package io.element.android.x.features.login.error
|
|||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import io.element.android.x.core.uri.isValidUrl
|
||||
import io.element.android.x.features.login.LoginFormState
|
||||
import io.element.android.x.element.resources.R as ElementR
|
||||
import io.element.android.x.features.login.LoginFormState
|
||||
|
||||
@Composable
|
||||
fun loginError(
|
||||
|
|
|
|||
|
|
@ -1,22 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="64dp"
|
||||
android:height="64dp"
|
||||
android:viewportWidth="64"
|
||||
android:viewportHeight="64">
|
||||
<path
|
||||
android:pathData="M23.04,3.84C23.04,1.7192 24.7593,0 26.88,0C41.0185,0 52.48,11.4615 52.48,25.6C52.48,27.7208 50.7608,29.44 48.64,29.44C46.5193,29.44 44.8,27.7208 44.8,25.6C44.8,15.7031 36.777,7.68 26.88,7.68C24.7593,7.68 23.04,5.9608 23.04,3.84Z"
|
||||
android:fillColor="#0DBD8B"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M40.96,60.16C40.96,62.2808 39.2407,64 37.12,64C22.9815,64 11.52,52.5385 11.52,38.4C11.52,36.2792 13.2392,34.56 15.36,34.56C17.4807,34.56 19.2,36.2792 19.2,38.4C19.2,48.2969 27.223,56.32 37.12,56.32C39.2407,56.32 40.96,58.0392 40.96,60.16Z"
|
||||
android:fillColor="#0DBD8B"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M3.84,40.96C1.7192,40.96 -0,39.2407 -0,37.12C-0,22.9815 11.4615,11.52 25.6,11.52C27.7208,11.52 29.44,13.2392 29.44,15.36C29.44,17.4807 27.7208,19.2 25.6,19.2C15.7031,19.2 7.68,27.223 7.68,37.12C7.68,39.2407 5.9608,40.96 3.84,40.96Z"
|
||||
android:fillColor="#0DBD8B"
|
||||
android:fillType="evenOdd"/>
|
||||
<path
|
||||
android:pathData="M60.16,23.04C62.2808,23.04 64,24.7593 64,26.88C64,41.0185 52.5385,52.48 38.4,52.48C36.2792,52.48 34.56,50.7608 34.56,48.64C34.56,46.5193 36.2792,44.8 38.4,44.8C48.2969,44.8 56.32,36.777 56.32,26.88C56.32,24.7593 58.0392,23.04 60.16,23.04Z"
|
||||
android:fillColor="#0DBD8B"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
||||
|
|
@ -1,5 +1,10 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M19,3H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5C21,3.9 20.1,3 19,3zM11,17H7v-4h4V17zM11,11H7V7h4V11zM17,17h-4v-4h4V17zM17,11h-4V7h4V11z"/>
|
||||
<vector android:height="24dp"
|
||||
android:tint="#000000"
|
||||
android:viewportHeight="24"
|
||||
android:viewportWidth="24"
|
||||
android:width="24dp"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M19,3H5C3.9,3 3,3.9 3,5v14c0,1.1 0.9,2 2,2h14c1.1,0 2,-0.9 2,-2V5C21,3.9 20.1,3 19,3zM11,17H7v-4h4V17zM11,11H7V7h4V11zM17,17h-4v-4h4V17zM17,11h-4V7h4V11z" />
|
||||
</vector>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
package io.element.android.x.features.login
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
|
|
@ -14,4 +13,4 @@ class ExampleUnitTest {
|
|||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ dependencies {
|
|||
implementation(project(":libraries:textcomposer"))
|
||||
implementation(libs.mavericks.compose)
|
||||
implementation(libs.coil.compose)
|
||||
implementation(libs.timber)
|
||||
implementation(libs.datetime)
|
||||
implementation(libs.accompanist.flowlayout)
|
||||
implementation(libs.androidx.recyclerview)
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
package io.element.android.x.features.messages
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
|
|
@ -21,4 +19,4 @@ class ExampleInstrumentedTest {
|
|||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("io.element.android.x.features.messages.test", appContext.packageName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
|
|
|||
|
|
@ -9,12 +9,20 @@ import io.element.android.x.features.messages.model.AggregatedReaction
|
|||
import io.element.android.x.features.messages.model.MessagesItemGroupPosition
|
||||
import io.element.android.x.features.messages.model.MessagesItemReactionState
|
||||
import io.element.android.x.features.messages.model.MessagesTimelineItemState
|
||||
import io.element.android.x.features.messages.model.content.*
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemContent
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemEmoteContent
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemEncryptedContent
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemImageContent
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemNoticeContent
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemRedactedContent
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemTextContent
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemUnknownContent
|
||||
import io.element.android.x.features.messages.util.invalidateLast
|
||||
import io.element.android.x.matrix.MatrixClient
|
||||
import io.element.android.x.matrix.media.MediaResolver
|
||||
import io.element.android.x.matrix.room.MatrixRoom
|
||||
import io.element.android.x.matrix.timeline.MatrixTimelineItem
|
||||
import kotlin.system.measureTimeMillis
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
@ -28,7 +36,6 @@ import org.matrix.rustcomponents.sdk.FormattedBody
|
|||
import org.matrix.rustcomponents.sdk.MessageFormat
|
||||
import org.matrix.rustcomponents.sdk.MessageType
|
||||
import timber.log.Timber
|
||||
import kotlin.system.measureTimeMillis
|
||||
|
||||
class MessageTimelineItemStateFactory(
|
||||
private val client: MatrixClient,
|
||||
|
|
@ -83,7 +90,6 @@ class MessageTimelineItemStateFactory(
|
|||
timelineItemStates.emit(newTimelineItemStates)
|
||||
}
|
||||
|
||||
|
||||
private fun calculateAndApplyDiff(newTimelineItems: List<MatrixTimelineItem>) {
|
||||
val timeToDiff = measureTimeMillis {
|
||||
val diffCallback =
|
||||
|
|
@ -192,7 +198,6 @@ class MessageTimelineItemStateFactory(
|
|||
htmlDocument = messageType.content.formatted?.toHtmlDocument()
|
||||
)
|
||||
else -> MessagesTimelineItemUnknownContent
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -232,5 +237,4 @@ class MessageTimelineItemStateFactory(
|
|||
.resolve(url, kind = MediaResolver.Kind.Thumbnail(size.value))
|
||||
return AvatarData(name, model, size)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,26 @@
|
|||
|
||||
package io.element.android.x.features.messages
|
||||
|
||||
import Avatar
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.BoxScope
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.WindowInsets
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.statusBars
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.widthIn
|
||||
import androidx.compose.foundation.layout.wrapContentHeight
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListState
|
||||
import androidx.compose.foundation.lazy.items
|
||||
|
|
@ -20,8 +37,24 @@ import androidx.compose.material.icons.Icons
|
|||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.ArrowDownward
|
||||
import androidx.compose.material.rememberModalBottomSheetState
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.FloatingActionButton
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.SnackbarHost
|
||||
import androidx.compose.material3.SnackbarHostState
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.derivedStateOf
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Alignment.Companion.End
|
||||
import androidx.compose.ui.Alignment.Companion.Start
|
||||
|
|
@ -41,18 +74,40 @@ import com.airbnb.mvrx.compose.mavericksViewModel
|
|||
import io.element.android.x.core.compose.LogCompositions
|
||||
import io.element.android.x.core.compose.PairCombinedPreviewParameter
|
||||
import io.element.android.x.core.data.StableCharSequence
|
||||
import io.element.android.x.designsystem.components.avatar.Avatar
|
||||
import io.element.android.x.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.x.features.messages.components.*
|
||||
import io.element.android.x.features.messages.model.*
|
||||
import io.element.android.x.features.messages.model.content.*
|
||||
import io.element.android.x.features.messages.components.MessageEventBubble
|
||||
import io.element.android.x.features.messages.components.MessagesReactionsView
|
||||
import io.element.android.x.features.messages.components.MessagesTimelineItemEncryptedView
|
||||
import io.element.android.x.features.messages.components.MessagesTimelineItemImageView
|
||||
import io.element.android.x.features.messages.components.MessagesTimelineItemRedactedView
|
||||
import io.element.android.x.features.messages.components.MessagesTimelineItemTextView
|
||||
import io.element.android.x.features.messages.components.MessagesTimelineItemUnknownView
|
||||
import io.element.android.x.features.messages.components.TimelineItemActionsScreen
|
||||
import io.element.android.x.features.messages.model.AggregatedReaction
|
||||
import io.element.android.x.features.messages.model.MessagesItemGroupPosition
|
||||
import io.element.android.x.features.messages.model.MessagesItemGroupPositionProvider
|
||||
import io.element.android.x.features.messages.model.MessagesItemReactionState
|
||||
import io.element.android.x.features.messages.model.MessagesTimelineItemState
|
||||
import io.element.android.x.features.messages.model.MessagesViewState
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemContent
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemContentProvider
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemEncryptedContent
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemImageContent
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemRedactedContent
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemTextBasedContent
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemUnknownContent
|
||||
import io.element.android.x.features.messages.textcomposer.MessageComposerViewModel
|
||||
import io.element.android.x.features.messages.textcomposer.MessageComposerViewState
|
||||
import io.element.android.x.textcomposer.MessageComposerMode
|
||||
import io.element.android.x.textcomposer.TextComposer
|
||||
import java.lang.Math.random
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.launch
|
||||
import timber.log.Timber
|
||||
import java.lang.Math.random
|
||||
|
||||
@Composable
|
||||
fun MessagesScreen(
|
||||
|
|
@ -61,7 +116,6 @@ fun MessagesScreen(
|
|||
viewModel: MessagesViewModel = mavericksViewModel(argsFactory = { roomId }),
|
||||
composerViewModel: MessageComposerViewModel = mavericksViewModel(argsFactory = { roomId })
|
||||
) {
|
||||
|
||||
fun onSendMessage(textMessage: String) {
|
||||
viewModel.sendMessage(textMessage)
|
||||
composerViewModel.updateText("")
|
||||
|
|
@ -88,7 +142,7 @@ fun MessagesScreen(
|
|||
MessagesScreenContent(
|
||||
roomTitle = roomTitle,
|
||||
roomAvatar = roomAvatar,
|
||||
timelineItems = timelineItems().orEmpty(),
|
||||
timelineItems = timelineItems().orEmpty().toImmutableList(),
|
||||
hasMoreToLoad = hasMoreToLoad,
|
||||
onReachedLoadMore = viewModel::loadMore,
|
||||
onBackPressed = onBackPressed,
|
||||
|
|
@ -130,7 +184,7 @@ fun MessagesScreen(
|
|||
fun MessagesScreenContent(
|
||||
roomTitle: String?,
|
||||
roomAvatar: AvatarData?,
|
||||
timelineItems: List<MessagesTimelineItemState>,
|
||||
timelineItems: ImmutableList<MessagesTimelineItemState>,
|
||||
hasMoreToLoad: Boolean,
|
||||
onReachedLoadMore: () -> Unit,
|
||||
onBackPressed: () -> Unit,
|
||||
|
|
@ -146,9 +200,11 @@ fun MessagesScreenContent(
|
|||
composerCanSendMessage: Boolean,
|
||||
composerText: StableCharSequence?,
|
||||
snackbarHostState: SnackbarHostState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
LogCompositions(tag = "MessagesScreen", msg = "Content")
|
||||
Scaffold(
|
||||
modifier = modifier,
|
||||
contentWindowInsets = WindowInsets.statusBars,
|
||||
topBar = {
|
||||
MessagesTopAppBar(
|
||||
|
|
@ -187,7 +243,7 @@ fun MessagesScreenContent(
|
|||
|
||||
@Composable
|
||||
fun MessagesContent(
|
||||
timelineItems: List<MessagesTimelineItemState>,
|
||||
timelineItems: ImmutableList<MessagesTimelineItemState>,
|
||||
hasMoreToLoad: Boolean,
|
||||
onReachedLoadMore: () -> Unit,
|
||||
onSendMessage: (String) -> Unit,
|
||||
|
|
@ -203,7 +259,6 @@ fun MessagesContent(
|
|||
composerText: StableCharSequence?,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
|
||||
val lazyListState = rememberLazyListState()
|
||||
Column(
|
||||
modifier = modifier
|
||||
|
|
@ -249,9 +304,11 @@ fun MessagesContent(
|
|||
fun MessagesTopAppBar(
|
||||
roomTitle: String?,
|
||||
roomAvatar: AvatarData?,
|
||||
onBackPressed: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onBackPressed: () -> Unit = {},
|
||||
) {
|
||||
TopAppBar(
|
||||
modifier = modifier,
|
||||
navigationIcon = {
|
||||
IconButton(onClick = onBackPressed) {
|
||||
Icon(
|
||||
|
|
@ -282,7 +339,7 @@ fun MessagesTopAppBar(
|
|||
@Composable
|
||||
fun TimelineItems(
|
||||
lazyListState: LazyListState,
|
||||
timelineItems: List<MessagesTimelineItemState>,
|
||||
timelineItems: ImmutableList<MessagesTimelineItemState>,
|
||||
highlightedEventId: String?,
|
||||
modifier: Modifier = Modifier,
|
||||
hasMoreToLoad: Boolean = false,
|
||||
|
|
@ -322,7 +379,6 @@ fun TimelineItems(
|
|||
onLoadMore = onReachedLoadMore
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun MessagesTimelineItemState.key(): String {
|
||||
|
|
@ -339,7 +395,6 @@ private fun MessagesTimelineItemState.contentType(): Int {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
fun TimelineItemRow(
|
||||
timelineItem: MessagesTimelineItemState,
|
||||
|
|
@ -426,7 +481,6 @@ fun MessageEventRow(
|
|||
content = messageEvent.content,
|
||||
modifier = contentModifier
|
||||
)
|
||||
else -> TODO() /* compiler issue ? */
|
||||
}
|
||||
}
|
||||
MessagesReactionsView(
|
||||
|
|
@ -471,8 +525,8 @@ private fun MessageSenderInformation(
|
|||
@Composable
|
||||
internal fun BoxScope.MessagesScrollHelper(
|
||||
lazyListState: LazyListState,
|
||||
timelineItems: List<MessagesTimelineItemState>,
|
||||
onLoadMore: () -> Unit,
|
||||
timelineItems: ImmutableList<MessagesTimelineItemState>,
|
||||
onLoadMore: () -> Unit = {},
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val firstVisibleItemIndex by remember { derivedStateOf { lazyListState.firstVisibleItemIndex } }
|
||||
|
|
@ -526,7 +580,6 @@ internal fun BoxScope.MessagesScrollHelper(
|
|||
Icon(Icons.Default.ArrowDownward, "")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
@ -543,7 +596,6 @@ internal fun MessagesLoadingMoreIndicator() {
|
|||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MessagesItemGroupPositionToMessagesTimelineItemContentProvider :
|
||||
|
|
@ -551,6 +603,7 @@ class MessagesItemGroupPositionToMessagesTimelineItemContentProvider :
|
|||
MessagesItemGroupPositionProvider() to MessagesTimelineItemContentProvider()
|
||||
)
|
||||
|
||||
@Suppress("PreviewPublic")
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
fun TimelineItemsPreview(
|
||||
|
|
@ -559,7 +612,7 @@ fun TimelineItemsPreview(
|
|||
) {
|
||||
TimelineItems(
|
||||
lazyListState = LazyListState(),
|
||||
timelineItems = listOf(
|
||||
timelineItems = persistentListOf(
|
||||
// 3 items (First Middle Last) with isMine = false
|
||||
createMessageEvent(
|
||||
isMine = false,
|
||||
|
|
|
|||
|
|
@ -218,4 +218,4 @@ class MessagesViewModel @AssistedInject constructor(
|
|||
timeline.callback = null
|
||||
timeline.dispose()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,7 +13,13 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Shape
|
||||
import androidx.compose.ui.unit.dp
|
||||
import io.element.android.x.designsystem.*
|
||||
import io.element.android.x.designsystem.LocalIsDarkTheme
|
||||
import io.element.android.x.designsystem.MessageHighlightDark
|
||||
import io.element.android.x.designsystem.MessageHighlightLight
|
||||
import io.element.android.x.designsystem.SystemGrey5Dark
|
||||
import io.element.android.x.designsystem.SystemGrey5Light
|
||||
import io.element.android.x.designsystem.SystemGrey6Dark
|
||||
import io.element.android.x.designsystem.SystemGrey6Light
|
||||
import io.element.android.x.features.messages.model.MessagesItemGroupPosition
|
||||
|
||||
private val BUBBLE_RADIUS = 16.dp
|
||||
|
|
@ -26,9 +32,9 @@ fun MessageEventBubble(
|
|||
interactionSource: MutableInteractionSource,
|
||||
isHighlighted: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: () -> Unit,
|
||||
onLongClick: () -> Unit,
|
||||
content: @Composable () -> Unit,
|
||||
onClick: () -> Unit = {},
|
||||
onLongClick: () -> Unit = {},
|
||||
content: @Composable () -> Unit = {},
|
||||
) {
|
||||
fun bubbleShape(): Shape {
|
||||
return when (groupPosition) {
|
||||
|
|
@ -102,4 +108,4 @@ fun MessageEventBubble(
|
|||
shape = bubbleShape,
|
||||
content = content
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ fun MessagesReactionsView(
|
|||
reactionsState: MessagesItemReactionState,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
if(reactionsState.reactions.isEmpty()) return
|
||||
if (reactionsState.reactions.isEmpty()) return
|
||||
FlowRow(
|
||||
modifier = modifier,
|
||||
mainAxisSpacing = 2.dp,
|
||||
|
|
@ -53,4 +53,4 @@ fun MessagesReactionButton(reaction: AggregatedReaction, modifier: Modifier = Mo
|
|||
Text(text = reaction.count, color = MaterialTheme.colorScheme.secondary, fontSize = 12.sp)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,28 @@
|
|||
package io.element.android.x.features.messages.components
|
||||
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.imePadding
|
||||
import androidx.compose.foundation.layout.navigationBarsPadding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material.ExperimentalMaterialApi
|
||||
import androidx.compose.material.ListItem
|
||||
import androidx.compose.material.LocalContentColor
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.ModalBottomSheetLayout
|
||||
import androidx.compose.material.ModalBottomSheetState
|
||||
import androidx.compose.material.ModalBottomSheetValue
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalFocusManager
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.airbnb.mvrx.compose.collectAsState
|
||||
import io.element.android.x.designsystem.components.VectorIcon
|
||||
|
|
@ -21,7 +35,6 @@ import io.element.android.x.features.messages.model.MessagesTimelineItemState
|
|||
import io.element.android.x.features.messages.model.MessagesViewState
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemTextBasedContent
|
||||
import io.element.android.x.features.messages.textcomposer.MessageComposerViewModel
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.filter
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
|
|
@ -63,7 +76,6 @@ fun TimelineItemActionsScreen(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
ModalBottomSheetLayout(
|
||||
modifier = modifier,
|
||||
sheetState = modalBottomSheetState,
|
||||
|
|
@ -71,46 +83,47 @@ fun TimelineItemActionsScreen(
|
|||
SheetContent(
|
||||
actionsSheetState = itemActionsSheetState(),
|
||||
onActionClicked = ::onItemActionClicked,
|
||||
modifier = Modifier.navigationBarsPadding().imePadding()
|
||||
modifier = Modifier
|
||||
.navigationBarsPadding()
|
||||
.imePadding()
|
||||
)
|
||||
}
|
||||
) {}
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun SheetContent(
|
||||
actionsSheetState: MessagesItemActionsSheetState?,
|
||||
onActionClicked: (MessagesItemAction, MessagesTimelineItemState.MessageEvent) -> Unit,
|
||||
modifier: Modifier = Modifier
|
||||
modifier: Modifier = Modifier,
|
||||
onActionClicked: (MessagesItemAction, MessagesTimelineItemState.MessageEvent) -> Unit = { _, _ -> },
|
||||
) {
|
||||
if (actionsSheetState == null || actionsSheetState.actions.isEmpty()) {
|
||||
// Crashes if sheetContent size is zero
|
||||
Box(modifier = modifier.size(1.dp))
|
||||
return
|
||||
}
|
||||
LazyColumn(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
items(actionsSheetState.actions) {
|
||||
ListItem(
|
||||
modifier = Modifier.clickable {
|
||||
onActionClicked(it, actionsSheetState.targetItem)
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
text = it.title,
|
||||
color = if (it.destructive) MaterialTheme.colors.error else Color.Unspecified,
|
||||
)
|
||||
},
|
||||
icon = {
|
||||
VectorIcon(
|
||||
resourceId = it.icon,
|
||||
tint = if (it.destructive) MaterialTheme.colors.error else LocalContentColor.current,
|
||||
)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
LazyColumn(
|
||||
modifier = modifier
|
||||
.fillMaxWidth()
|
||||
) {
|
||||
items(actionsSheetState.actions) {
|
||||
ListItem(
|
||||
modifier = Modifier.clickable {
|
||||
onActionClicked(it, actionsSheetState.targetItem)
|
||||
},
|
||||
text = {
|
||||
Text(
|
||||
text = it.title,
|
||||
color = if (it.destructive) MaterialTheme.colors.error else Color.Unspecified,
|
||||
)
|
||||
},
|
||||
icon = {
|
||||
VectorIcon(
|
||||
resourceId = it.icon,
|
||||
tint = if (it.destructive) MaterialTheme.colors.error else LocalContentColor.current,
|
||||
)
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,4 +17,4 @@ fun MessagesTimelineItemEncryptedView(
|
|||
icon = Icons.Default.Warning,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import androidx.compose.foundation.ExperimentalFoundationApi
|
|||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.aspectRatio
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
|
|
@ -16,7 +15,6 @@ import androidx.compose.ui.Modifier
|
|||
import androidx.compose.ui.graphics.painter.ColorPainter
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.unit.dp
|
||||
import coil.compose.AsyncImage
|
||||
import coil.request.ImageRequest
|
||||
import io.element.android.x.features.messages.model.content.MessagesTimelineItemImageContent
|
||||
|
|
@ -26,9 +24,9 @@ fun MessagesTimelineItemImageView(
|
|||
content: MessagesTimelineItemImageContent,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val widthPercent = if(content.aspectRatio > 1f){
|
||||
val widthPercent = if (content.aspectRatio > 1f) {
|
||||
1f
|
||||
}else {
|
||||
} else {
|
||||
0.7f
|
||||
}
|
||||
Box(
|
||||
|
|
@ -37,7 +35,6 @@ fun MessagesTimelineItemImageView(
|
|||
.aspectRatio(content.aspectRatio),
|
||||
contentAlignment = Alignment.Center,
|
||||
) {
|
||||
|
||||
var isLoading = rememberSaveable(content.imageMeta) { mutableStateOf(true) }
|
||||
val context = LocalContext.current
|
||||
val model = ImageRequest.Builder(context)
|
||||
|
|
@ -52,4 +49,4 @@ fun MessagesTimelineItemImageView(
|
|||
onSuccess = { isLoading.value = false },
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,4 +40,4 @@ fun MessagesTimelineItemInformativeView(
|
|||
text = text
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,4 +17,4 @@ fun MessagesTimelineItemRedactedView(
|
|||
icon = Icons.Default.Delete,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ fun MessagesTimelineItemTextView(
|
|||
content: MessagesTimelineItemTextBasedContent,
|
||||
interactionSource: MutableInteractionSource,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit,
|
||||
onTextLongClicked: () -> Unit,
|
||||
onTextClicked: () -> Unit = {},
|
||||
onTextLongClicked: () -> Unit = {},
|
||||
) {
|
||||
val htmlDocument = content.htmlDocument
|
||||
if (htmlDocument != null) {
|
||||
|
|
@ -74,4 +74,4 @@ private fun String.linkify(
|
|||
end = end
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,4 +17,4 @@ fun MessagesTimelineItemUnknownView(
|
|||
icon = Icons.Default.Info,
|
||||
modifier = modifier
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,17 +9,25 @@ import androidx.compose.foundation.layout.padding
|
|||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.InlineTextContent
|
||||
import androidx.compose.foundation.text.appendInlineContent
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.ColorScheme
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.drawBehind
|
||||
import androidx.compose.ui.geometry.Offset
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.*
|
||||
import androidx.compose.ui.text.AnnotatedString
|
||||
import androidx.compose.ui.text.SpanStyle
|
||||
import androidx.compose.ui.text.TextStyle
|
||||
import androidx.compose.ui.text.buildAnnotatedString
|
||||
import androidx.compose.ui.text.font.FontFamily
|
||||
import androidx.compose.ui.text.font.FontStyle
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.google.accompanist.flowlayout.FlowRow
|
||||
|
|
@ -27,6 +35,7 @@ import io.element.android.x.designsystem.LinkColor
|
|||
import io.element.android.x.designsystem.components.ClickableLinkText
|
||||
import io.element.android.x.matrix.permalink.PermalinkData
|
||||
import io.element.android.x.matrix.permalink.PermalinkParser
|
||||
import kotlinx.collections.immutable.persistentMapOf
|
||||
import org.jsoup.nodes.Document
|
||||
import org.jsoup.nodes.Element
|
||||
import org.jsoup.nodes.Node
|
||||
|
|
@ -38,34 +47,33 @@ private const val chipId = "chip"
|
|||
fun HtmlDocument(
|
||||
document: Document,
|
||||
interactionSource: MutableInteractionSource,
|
||||
onTextClicked: () -> Unit,
|
||||
onTextLongClicked: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit = {},
|
||||
onTextLongClicked: () -> Unit = {},
|
||||
) {
|
||||
HtmlBody(
|
||||
body = document.body(),
|
||||
interactionSource = interactionSource,
|
||||
modifier = modifier,
|
||||
onTextClicked = onTextClicked,
|
||||
onTextLongClicked = onTextLongClicked,
|
||||
interactionSource = interactionSource
|
||||
)
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun HtmlBody(
|
||||
body: Element,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit,
|
||||
onTextLongClicked: () -> Unit,
|
||||
interactionSource: MutableInteractionSource,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit = {},
|
||||
onTextLongClicked: () -> Unit = {},
|
||||
) {
|
||||
|
||||
@Composable
|
||||
fun NodesFlowRode(
|
||||
nodes: Iterator<Node>,
|
||||
onTextClicked: () -> Unit,
|
||||
onTextLongClicked: () -> Unit,
|
||||
interactionSource: MutableInteractionSource,
|
||||
onTextClicked: () -> Unit = {},
|
||||
onTextLongClicked: () -> Unit = {},
|
||||
) = FlowRow(
|
||||
mainAxisSpacing = 2.dp,
|
||||
crossAxisSpacing = 8.dp,
|
||||
|
|
@ -106,9 +114,9 @@ private fun HtmlBody(
|
|||
while (nodesIterator.hasNext()) {
|
||||
NodesFlowRode(
|
||||
nodes = nodesIterator,
|
||||
interactionSource = interactionSource,
|
||||
onTextClicked = onTextClicked,
|
||||
onTextLongClicked = onTextLongClicked,
|
||||
interactionSource = interactionSource
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -125,10 +133,10 @@ private fun Element.isInline(): Boolean {
|
|||
@Composable
|
||||
private fun HtmlBlock(
|
||||
element: Element,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit,
|
||||
onTextLongClicked: () -> Unit,
|
||||
interactionSource: MutableInteractionSource,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit = {},
|
||||
onTextLongClicked: () -> Unit = {},
|
||||
) {
|
||||
val blockModifier = modifier
|
||||
.padding(top = 4.dp)
|
||||
|
|
@ -183,10 +191,10 @@ private fun HtmlBlock(
|
|||
@Composable
|
||||
private fun HtmlInline(
|
||||
element: Element,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit,
|
||||
onTextLongClicked: () -> Unit,
|
||||
interactionSource: MutableInteractionSource,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit = {},
|
||||
onTextLongClicked: () -> Unit = {},
|
||||
) {
|
||||
Box(modifier) {
|
||||
val styledText = buildAnnotatedString {
|
||||
|
|
@ -202,7 +210,10 @@ private fun HtmlInline(
|
|||
}
|
||||
|
||||
@Composable
|
||||
private fun HtmlPreformatted(pre: Element, modifier: Modifier = Modifier) {
|
||||
private fun HtmlPreformatted(
|
||||
pre: Element,
|
||||
modifier: Modifier = Modifier
|
||||
) {
|
||||
val isCode = pre.firstElementChild()?.normalName() == "code"
|
||||
val backgroundColor =
|
||||
if (isCode) MaterialTheme.colorScheme.codeBackground() else Color.Unspecified
|
||||
|
|
@ -221,9 +232,10 @@ private fun HtmlPreformatted(pre: Element, modifier: Modifier = Modifier) {
|
|||
@Composable
|
||||
private fun HtmlParagraph(
|
||||
paragraph: Element,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit, onTextLongClicked: () -> Unit,
|
||||
interactionSource: MutableInteractionSource,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit = {},
|
||||
onTextLongClicked: () -> Unit = {},
|
||||
) {
|
||||
Box(modifier) {
|
||||
val styledText = buildAnnotatedString {
|
||||
|
|
@ -239,9 +251,10 @@ private fun HtmlParagraph(
|
|||
@Composable
|
||||
private fun HtmlBlockquote(
|
||||
blockquote: Element,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit, onTextLongClicked: () -> Unit,
|
||||
interactionSource: MutableInteractionSource,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit = {},
|
||||
onTextLongClicked: () -> Unit = {},
|
||||
) {
|
||||
val color = MaterialTheme.colorScheme.onBackground
|
||||
Box(
|
||||
|
|
@ -268,13 +281,13 @@ private fun HtmlBlockquote(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
private fun HtmlHeading(
|
||||
heading: Element,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit, onTextLongClicked: () -> Unit,
|
||||
interactionSource: MutableInteractionSource,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit = {},
|
||||
onTextLongClicked: () -> Unit = {},
|
||||
) {
|
||||
val style = when (heading.normalName()) {
|
||||
"h1" -> MaterialTheme.typography.headlineLarge.copy(fontSize = 30.sp)
|
||||
|
|
@ -304,9 +317,10 @@ private fun HtmlHeading(
|
|||
@Composable
|
||||
private fun HtmlMxReply(
|
||||
mxReply: Element,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit, onTextLongClicked: () -> Unit,
|
||||
interactionSource: MutableInteractionSource,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit = {},
|
||||
onTextLongClicked: () -> Unit = {},
|
||||
) {
|
||||
val blockquote = mxReply.childNodes().firstOrNull() ?: return
|
||||
val shape = RoundedCornerShape(12.dp)
|
||||
|
|
@ -356,9 +370,10 @@ private fun HtmlMxReply(
|
|||
@Composable
|
||||
private fun HtmlOrderedList(
|
||||
orderedList: Element,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit, onTextLongClicked: () -> Unit,
|
||||
interactionSource: MutableInteractionSource,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit = {},
|
||||
onTextLongClicked: () -> Unit = {},
|
||||
) {
|
||||
var number = 1
|
||||
val delimiter = "."
|
||||
|
|
@ -381,9 +396,10 @@ private fun HtmlOrderedList(
|
|||
@Composable
|
||||
private fun HtmlUnorderedList(
|
||||
unorderedList: Element,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit, onTextLongClicked: () -> Unit,
|
||||
interactionSource: MutableInteractionSource,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit = {},
|
||||
onTextLongClicked: () -> Unit = {},
|
||||
) {
|
||||
val marker = "・"
|
||||
HtmlListItems(
|
||||
|
|
@ -402,14 +418,14 @@ private fun HtmlUnorderedList(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@Composable
|
||||
private fun HtmlListItems(
|
||||
list: Element,
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit, onTextLongClicked: () -> Unit,
|
||||
interactionSource: MutableInteractionSource,
|
||||
content: @Composable (node: TextNode) -> Unit
|
||||
modifier: Modifier = Modifier,
|
||||
onTextClicked: () -> Unit = {},
|
||||
onTextLongClicked: () -> Unit = {},
|
||||
content: @Composable (node: TextNode) -> Unit = {}
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
for (node in list.children()) {
|
||||
|
|
@ -420,13 +436,12 @@ private fun HtmlListItems(
|
|||
}
|
||||
is Element -> HtmlBlock(
|
||||
element = innerNode,
|
||||
modifier = modifier.padding(start = 4.dp),
|
||||
modifier = Modifier.padding(start = 4.dp),
|
||||
onTextClicked = onTextClicked, onTextLongClicked = onTextLongClicked,
|
||||
interactionSource = interactionSource
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -439,7 +454,6 @@ private fun AnnotatedString.Builder.appendInlineChildrenElements(
|
|||
childNodes: List<Node>,
|
||||
colors: ColorScheme
|
||||
) {
|
||||
|
||||
for (node in childNodes) {
|
||||
when (node) {
|
||||
is TextNode -> {
|
||||
|
|
@ -452,7 +466,6 @@ private fun AnnotatedString.Builder.appendInlineChildrenElements(
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
private fun AnnotatedString.Builder.appendInlineElement(element: Element, colors: ColorScheme) {
|
||||
when (element.normalName()) {
|
||||
"br" -> {
|
||||
|
|
@ -490,7 +503,6 @@ private fun AnnotatedString.Builder.appendInlineElement(element: Element, colors
|
|||
appendInlineChildrenElements(element.childNodes(), colors)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun AnnotatedString.Builder.appendLink(link: Element) {
|
||||
|
|
@ -521,13 +533,13 @@ private fun AnnotatedString.Builder.appendLink(link: Element) {
|
|||
@Composable
|
||||
private fun HtmlText(
|
||||
text: AnnotatedString,
|
||||
interactionSource: MutableInteractionSource,
|
||||
modifier: Modifier = Modifier,
|
||||
style: TextStyle = LocalTextStyle.current,
|
||||
onClick: () -> Unit,
|
||||
onLongClick: () -> Unit,
|
||||
interactionSource: MutableInteractionSource,
|
||||
onClick: () -> Unit = {},
|
||||
onLongClick: () -> Unit = {},
|
||||
) {
|
||||
val inlineContentMap = emptyMap<String, InlineTextContent>()
|
||||
val inlineContentMap = persistentMapOf<String, InlineTextContent>()
|
||||
ClickableLinkText(
|
||||
text = text,
|
||||
linkAnnotationTag = "URL",
|
||||
|
|
@ -539,4 +551,3 @@ private fun HtmlText(
|
|||
onLongClick = onLongClick
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -37,5 +37,4 @@ internal class CacheInvalidator(private val itemStatesCache: MutableList<Message
|
|||
itemStatesCache.removeAt(position)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,5 +31,4 @@ internal class MatrixTimelineItemsDiffCallback(
|
|||
val newItem = newList.getOrNull(newItemPosition)
|
||||
return oldItem == newItem
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,4 +15,4 @@ sealed class MessagesItemAction(
|
|||
object Redact : MessagesItemAction("Redact", VectorIcons.Delete, destructive = true)
|
||||
object Reply : MessagesItemAction("Reply", VectorIcons.Reply)
|
||||
object Edit : MessagesItemAction("Edit", VectorIcons.Edit)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ sealed interface MessagesItemGroupPosition {
|
|||
First, None -> true
|
||||
else -> false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class MessagesItemGroupPositionProvider : PreviewParameterProvider<MessagesItemGroupPosition> {
|
||||
|
|
@ -22,4 +21,4 @@ internal class MessagesItemGroupPositionProvider : PreviewParameterProvider<Mess
|
|||
MessagesItemGroupPosition.Last,
|
||||
MessagesItemGroupPosition.None,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,9 +6,10 @@ import androidx.compose.runtime.Stable
|
|||
data class MessagesItemReactionState(
|
||||
val reactions: List<AggregatedReaction>
|
||||
)
|
||||
|
||||
@Stable
|
||||
data class AggregatedReaction(
|
||||
val key: String,
|
||||
val count: String,
|
||||
val isHighlighted: Boolean = false
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -23,11 +23,5 @@ sealed interface MessagesTimelineItemState {
|
|||
val showSenderInformation = groupPosition.isNew() && !isMine
|
||||
|
||||
val safeSenderName: String = senderDisplayName ?: senderId
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,6 @@ package io.element.android.x.features.messages.model.content
|
|||
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import org.matrix.rustcomponents.sdk.EncryptedMessage
|
||||
import org.matrix.rustcomponents.sdk.FormattedBody
|
||||
import org.matrix.rustcomponents.sdk.MessageFormat
|
||||
|
||||
sealed interface MessagesTimelineItemContent
|
||||
|
||||
|
|
@ -28,4 +26,4 @@ class MessagesTimelineItemContentProvider : PreviewParameterProvider<MessagesTim
|
|||
),
|
||||
MessagesTimelineItemUnknownContent,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@ import org.jsoup.nodes.Document
|
|||
data class MessagesTimelineItemEmoteContent(
|
||||
override val body: String,
|
||||
override val htmlDocument: Document?
|
||||
) : MessagesTimelineItemTextBasedContent
|
||||
) : MessagesTimelineItemTextBasedContent
|
||||
|
|
|
|||
|
|
@ -4,4 +4,4 @@ import org.matrix.rustcomponents.sdk.EncryptedMessage
|
|||
|
||||
data class MessagesTimelineItemEncryptedContent(
|
||||
val encryptedMessage: EncryptedMessage
|
||||
) : MessagesTimelineItemContent
|
||||
) : MessagesTimelineItemContent
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@ data class MessagesTimelineItemImageContent(
|
|||
val imageMeta: MediaResolver.Meta,
|
||||
val blurhash: String?,
|
||||
val aspectRatio: Float
|
||||
) : MessagesTimelineItemContent
|
||||
) : MessagesTimelineItemContent
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@ import org.jsoup.nodes.Document
|
|||
data class MessagesTimelineItemNoticeContent(
|
||||
override val body: String,
|
||||
override val htmlDocument: Document?
|
||||
) : MessagesTimelineItemTextBasedContent
|
||||
) : MessagesTimelineItemTextBasedContent
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
package io.element.android.x.features.messages.model.content
|
||||
|
||||
object MessagesTimelineItemRedactedContent : MessagesTimelineItemContent
|
||||
object MessagesTimelineItemRedactedContent : MessagesTimelineItemContent
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@ import org.jsoup.nodes.Document
|
|||
sealed interface MessagesTimelineItemTextBasedContent : MessagesTimelineItemContent {
|
||||
val body: String
|
||||
val htmlDocument: Document?
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@ import org.jsoup.nodes.Document
|
|||
data class MessagesTimelineItemTextContent(
|
||||
override val body: String,
|
||||
override val htmlDocument: Document?
|
||||
) : MessagesTimelineItemTextBasedContent
|
||||
) : MessagesTimelineItemTextBasedContent
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
package io.element.android.x.features.messages.model.content
|
||||
|
||||
object MessagesTimelineItemUnknownContent : MessagesTimelineItemContent
|
||||
object MessagesTimelineItemUnknownContent : MessagesTimelineItemContent
|
||||
|
|
|
|||
|
|
@ -35,4 +35,4 @@ class MessageComposerViewModel @AssistedInject constructor(
|
|||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,4 +16,4 @@ data class MessageComposerViewState(
|
|||
// val voiceBroadcastState: VoiceBroadcastState? = null,
|
||||
val text: StableCharSequence? = null,
|
||||
val isFullScreen: Boolean = false,
|
||||
) : MavericksState
|
||||
) : MavericksState
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@ internal inline fun <reified T> MutableList<T?>.invalidateLast() {
|
|||
if (indexOfLast > 0) {
|
||||
set(indexOfLast - 1, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
package io.element.android.x.features.messages
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
|
|
@ -14,4 +13,4 @@ class ExampleUnitTest {
|
|||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,9 @@ dependencies {
|
|||
implementation(project(":libraries:elementresources"))
|
||||
implementation(project(":libraries:designsystem"))
|
||||
implementation(libs.mavericks.compose)
|
||||
implementation(libs.timber)
|
||||
implementation(libs.accompanist.pager)
|
||||
implementation(libs.accompanist.pagerindicator)
|
||||
testImplementation(libs.test.junit)
|
||||
androidTestImplementation(libs.test.junitext)
|
||||
ksp(libs.showkase.processor)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
package io.element.android.x.features.login
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
|
|
@ -21,4 +19,4 @@ class ExampleInstrumentedTest {
|
|||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("io.element.android.x.features.login.test", appContext.packageName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
|
|
|||
|
|
@ -3,12 +3,24 @@
|
|||
package io.element.android.x.features.onboarding
|
||||
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.layout.systemBarsPadding
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.snapshotFlow
|
||||
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
|
|
@ -42,19 +54,20 @@ fun OnBoardingScreen(
|
|||
)
|
||||
}
|
||||
|
||||
|
||||
@OptIn(ExperimentalPagerApi::class)
|
||||
@Composable
|
||||
fun OnBoardingContent(
|
||||
state: OnBoardingViewState,
|
||||
onPageChanged: (Int) -> Unit,
|
||||
onSignUp: () -> Unit,
|
||||
onSignIn: () -> Unit,
|
||||
modifier: Modifier = Modifier,
|
||||
onPageChanged: (Int) -> Unit = {},
|
||||
onSignUp: () -> Unit = {},
|
||||
onSignIn: () -> Unit = {},
|
||||
) {
|
||||
val carrouselState = remember { SplashCarouselStateFactory().create() }
|
||||
val nbOfPages = carrouselState.items.size
|
||||
var key by remember { mutableStateOf(false) }
|
||||
Surface(
|
||||
modifier = modifier,
|
||||
color = MaterialTheme.colorScheme.background,
|
||||
) {
|
||||
Box(
|
||||
|
|
@ -125,8 +138,11 @@ fun OnBoardingContent(
|
|||
@Composable
|
||||
fun OnBoardingPage(
|
||||
item: SplashCarouselState.Item,
|
||||
modifier: Modifier = Modifier,
|
||||
) {
|
||||
Box {
|
||||
Box(
|
||||
modifier = modifier,
|
||||
) {
|
||||
/*
|
||||
Image(
|
||||
painterResource(id = item.pageBackground),
|
||||
|
|
@ -164,4 +180,4 @@ fun OnBoardingPage(
|
|||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,4 +12,4 @@ class OnBoardingViewModel(initialState: OnBoardingViewState) :
|
|||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,12 +20,12 @@ import androidx.annotation.DrawableRes
|
|||
import androidx.annotation.StringRes
|
||||
|
||||
data class SplashCarouselState(
|
||||
val items: List<Item>
|
||||
val items: List<Item>
|
||||
) {
|
||||
data class Item(
|
||||
@StringRes val title: Int,
|
||||
@StringRes val body: Int,
|
||||
@DrawableRes val image: Int,
|
||||
@DrawableRes val pageBackground: Int
|
||||
@StringRes val title: Int,
|
||||
@StringRes val body: Int,
|
||||
@DrawableRes val image: Int,
|
||||
@DrawableRes val pageBackground: Int
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package io.element.android.x.features.onboarding
|
|||
import androidx.annotation.DrawableRes
|
||||
import io.element.android.x.element.resources.R as ElementR
|
||||
|
||||
class SplashCarouselStateFactory() {
|
||||
class SplashCarouselStateFactory {
|
||||
fun create(): SplashCarouselState {
|
||||
val lightTheme = true
|
||||
fun background(@DrawableRes lightDrawable: Int) =
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
package io.element.android.x.features.login
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
|
|
@ -14,4 +13,4 @@ class ExampleUnitTest {
|
|||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,10 +20,9 @@ dependencies {
|
|||
implementation(project(":libraries:matrix"))
|
||||
implementation(project(":libraries:designsystem"))
|
||||
implementation(libs.mavericks.compose)
|
||||
implementation(libs.timber)
|
||||
implementation(libs.datetime)
|
||||
implementation(libs.accompanist.placeholder)
|
||||
testImplementation(libs.test.junit)
|
||||
androidTestImplementation(libs.test.junitext)
|
||||
ksp(libs.showkase.processor)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,11 @@
|
|||
package io.element.android.x.features.roomlist
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
|
|
@ -21,4 +19,4 @@ class ExampleInstrumentedTest {
|
|||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("io.element.android.x.features.roomlist.test", appContext.packageName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<manifest>
|
||||
|
||||
</manifest>
|
||||
</manifest>
|
||||
|
|
|
|||
|
|
@ -2,12 +2,18 @@ package io.element.android.x.features.roomlist
|
|||
|
||||
import android.text.format.DateFormat
|
||||
import android.text.format.DateUtils
|
||||
import kotlinx.datetime.*
|
||||
import kotlinx.datetime.TimeZone
|
||||
import java.time.Period
|
||||
import java.time.format.DateTimeFormatter
|
||||
import java.util.*
|
||||
import java.util.Locale
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlinx.datetime.Clock
|
||||
import kotlinx.datetime.Instant
|
||||
import kotlinx.datetime.LocalDateTime
|
||||
import kotlinx.datetime.TimeZone
|
||||
import kotlinx.datetime.toInstant
|
||||
import kotlinx.datetime.toJavaLocalDate
|
||||
import kotlinx.datetime.toJavaLocalDateTime
|
||||
import kotlinx.datetime.toLocalDateTime
|
||||
|
||||
class LastMessageFormatter(
|
||||
private val clock: Clock = Clock.System,
|
||||
|
|
@ -29,7 +35,6 @@ class LastMessageFormatter(
|
|||
DateTimeFormatter.ofPattern(pattern)
|
||||
}
|
||||
|
||||
|
||||
fun format(timestamp: Long?): String {
|
||||
if (timestamp == null) return ""
|
||||
val now: Instant = clock.now()
|
||||
|
|
@ -77,6 +82,4 @@ class LastMessageFormatter(
|
|||
DateUtils.FORMAT_SHOW_WEEKDAY
|
||||
).toString()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ import io.element.android.x.features.roomlist.model.RoomListRoomSummary
|
|||
import io.element.android.x.features.roomlist.model.RoomListViewState
|
||||
import io.element.android.x.features.roomlist.model.stubbedRoomSummaries
|
||||
import io.element.android.x.matrix.core.RoomId
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.toImmutableList
|
||||
|
||||
@Composable
|
||||
fun RoomListScreen(
|
||||
|
|
@ -53,7 +55,7 @@ fun RoomListScreen(
|
|||
val roomSummaries by viewModel.collectAsState(RoomListViewState::rooms)
|
||||
val matrixUser by viewModel.collectAsState(RoomListViewState::user)
|
||||
RoomListContent(
|
||||
roomSummaries = roomSummaries().orEmpty(),
|
||||
roomSummaries = roomSummaries().orEmpty().toImmutableList(),
|
||||
matrixUser = matrixUser(),
|
||||
onRoomClicked = onRoomClicked,
|
||||
onLogoutClicked = viewModel::logout,
|
||||
|
|
@ -66,16 +68,16 @@ fun RoomListScreen(
|
|||
|
||||
@Composable
|
||||
fun RoomListContent(
|
||||
roomSummaries: List<RoomListRoomSummary>,
|
||||
roomSummaries: ImmutableList<RoomListRoomSummary>,
|
||||
matrixUser: MatrixUser?,
|
||||
onRoomClicked: (RoomId) -> Unit,
|
||||
filter: String,
|
||||
onFilterChanged: (String) -> Unit,
|
||||
onLogoutClicked: () -> Unit,
|
||||
onScrollOver: (IntRange) -> Unit,
|
||||
isLoginOut: Boolean,
|
||||
modifier: Modifier = Modifier,
|
||||
onRoomClicked: (RoomId) -> Unit = {},
|
||||
onFilterChanged: (String) -> Unit = {},
|
||||
onLogoutClicked: () -> Unit = {},
|
||||
onScrollOver: (IntRange) -> Unit = {},
|
||||
) {
|
||||
|
||||
fun onRoomClicked(room: RoomListRoomSummary) {
|
||||
onRoomClicked(room.roomId)
|
||||
}
|
||||
|
|
@ -104,7 +106,7 @@ fun RoomListContent(
|
|||
}
|
||||
|
||||
Scaffold(
|
||||
modifier = Modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
modifier = modifier.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
topBar = {
|
||||
RoomListTopBar(
|
||||
matrixUser = matrixUser,
|
||||
|
|
@ -133,7 +135,7 @@ fun RoomListContent(
|
|||
}
|
||||
)
|
||||
if (isLoginOut) {
|
||||
ProgressDialog("Login out...")
|
||||
ProgressDialog(text = "Login out...")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -176,4 +178,3 @@ fun PreviewableDarkRoomListContent() {
|
|||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,17 +4,15 @@ import com.airbnb.mvrx.*
|
|||
import dagger.assisted.Assisted
|
||||
import dagger.assisted.AssistedInject
|
||||
import io.element.android.x.anvilannotations.ContributesViewModel
|
||||
import io.element.android.x.core.data.parallelMap
|
||||
import io.element.android.x.core.coroutine.parallelMap
|
||||
import io.element.android.x.core.di.daggerMavericksViewModelFactory
|
||||
import io.element.android.x.designsystem.components.avatar.AvatarData
|
||||
import io.element.android.x.designsystem.components.avatar.AvatarSize
|
||||
import io.element.android.x.di.AppScope
|
||||
import io.element.android.x.di.SessionScope
|
||||
import io.element.android.x.features.roomlist.model.MatrixUser
|
||||
import io.element.android.x.features.roomlist.model.RoomListRoomSummary
|
||||
import io.element.android.x.features.roomlist.model.RoomListRoomSummaryPlaceholders
|
||||
import io.element.android.x.features.roomlist.model.RoomListViewState
|
||||
import io.element.android.x.matrix.Matrix
|
||||
import io.element.android.x.matrix.MatrixClient
|
||||
import io.element.android.x.matrix.media.MediaResolver
|
||||
import io.element.android.x.matrix.room.RoomSummary
|
||||
|
|
@ -112,8 +110,8 @@ class RoomListViewModel @AssistedInject constructor(
|
|||
copy(
|
||||
rooms = when {
|
||||
it is Loading ||
|
||||
// Note: this second case will prevent to handle correctly the empty case
|
||||
(it is Success && it().isEmpty() && filter.isEmpty()) -> {
|
||||
// Note: this second case will prevent to handle correctly the empty case
|
||||
(it is Success && it().isEmpty() && filter.isEmpty()) -> {
|
||||
// Show fake placeholders to avoid having empty screen
|
||||
Loading(RoomListRoomSummaryPlaceholders.createFakeList(size = 16))
|
||||
}
|
||||
|
|
@ -158,5 +156,4 @@ class RoomListViewModel @AssistedInject constructor(
|
|||
.resolve(url, kind = MediaResolver.Kind.Thumbnail(size.value))
|
||||
return AvatarData(name, model, size)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
package io.element.android.x.features.roomlist.components
|
||||
|
||||
import Avatar
|
||||
import androidx.activity.compose.BackHandler
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.material.ContentAlpha
|
||||
|
|
@ -11,9 +10,23 @@ import androidx.compose.material.icons.filled.ArrowBack
|
|||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.Logout
|
||||
import androidx.compose.material.icons.filled.Search
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.MediumTopAppBar
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextField
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.material3.TopAppBar
|
||||
import androidx.compose.material3.TopAppBarScrollBehavior
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
|
|
@ -24,6 +37,7 @@ import androidx.compose.ui.text.font.FontWeight
|
|||
import androidx.compose.ui.unit.sp
|
||||
import io.element.android.x.core.compose.LogCompositions
|
||||
import io.element.android.x.core.compose.textFieldState
|
||||
import io.element.android.x.designsystem.components.avatar.Avatar
|
||||
import io.element.android.x.designsystem.components.dialogs.ConfirmationDialog
|
||||
import io.element.android.x.features.roomlist.model.MatrixUser
|
||||
|
||||
|
|
@ -35,7 +49,6 @@ fun RoomListTopBar(
|
|||
onLogoutClicked: () -> Unit,
|
||||
scrollBehavior: TopAppBarScrollBehavior
|
||||
) {
|
||||
|
||||
LogCompositions(tag = "RoomListScreen", msg = "TopBar")
|
||||
var searchWidgetStateIsOpened by rememberSaveable { mutableStateOf(false) }
|
||||
|
||||
|
|
@ -65,20 +78,20 @@ fun RoomListTopBar(
|
|||
scrollBehavior = scrollBehavior,
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun SearchRoomListTopBar(
|
||||
text: String,
|
||||
onFilterChanged: (String) -> Unit,
|
||||
onCloseClicked: () -> Unit,
|
||||
scrollBehavior: TopAppBarScrollBehavior
|
||||
scrollBehavior: TopAppBarScrollBehavior,
|
||||
modifier: Modifier = Modifier,
|
||||
onFilterChanged: (String) -> Unit = {},
|
||||
onCloseClicked: () -> Unit = {},
|
||||
) {
|
||||
var filterState by textFieldState(stateValue = text)
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
TopAppBar(
|
||||
modifier = Modifier
|
||||
modifier = modifier
|
||||
.nestedScroll(scrollBehavior.nestedScrollConnection),
|
||||
title = {
|
||||
TextField(
|
||||
|
|
@ -184,10 +197,13 @@ private fun DefaultRoomListTopBar(
|
|||
)
|
||||
// Log out confirmation dialog
|
||||
ConfirmationDialog(
|
||||
openDialog,
|
||||
isDisplayed = openDialog.value,
|
||||
title = "Log out",
|
||||
content = "Do you confirm you want to log out?",
|
||||
submitText = "Log out",
|
||||
onSubmitClicked = onLogoutClicked,
|
||||
onDismiss = {
|
||||
openDialog.value = false
|
||||
}
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1,23 @@
|
|||
package io.element.android.x.features.roomlist.components
|
||||
|
||||
import Avatar
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.IntrinsicSize
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material.ripple.rememberRipple
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.Immutable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Alignment.Companion.CenterVertically
|
||||
|
|
@ -29,17 +36,17 @@ import androidx.compose.ui.unit.LayoutDirection
|
|||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.google.accompanist.placeholder.material.placeholder
|
||||
import io.element.android.x.designsystem.components.avatar.Avatar
|
||||
import io.element.android.x.features.roomlist.model.RoomListRoomSummary
|
||||
|
||||
private val minHeight = 72.dp
|
||||
|
||||
@Composable
|
||||
internal fun RoomSummaryRow(
|
||||
modifier: Modifier = Modifier,
|
||||
room: RoomListRoomSummary,
|
||||
onClick: (RoomListRoomSummary) -> Unit
|
||||
modifier: Modifier = Modifier,
|
||||
onClick: (RoomListRoomSummary) -> Unit = {},
|
||||
) {
|
||||
|
||||
val clickModifier = if (room.isPlaceholder) {
|
||||
modifier
|
||||
} else {
|
||||
|
|
@ -57,7 +64,6 @@ internal fun RoomSummaryRow(
|
|||
) {
|
||||
DefaultRoomSummaryRow(room = room)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -13,4 +13,5 @@ data class RoomListRoomSummary(
|
|||
val timestamp: String? = null,
|
||||
val lastMessage: CharSequence? = null,
|
||||
val avatarData: AvatarData = AvatarData(),
|
||||
val isPlaceholder: Boolean = false,)
|
||||
val isPlaceholder: Boolean = false,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ package io.element.android.x.features.roomlist.model
|
|||
|
||||
import io.element.android.x.designsystem.components.avatar.AvatarData
|
||||
|
||||
|
||||
object RoomListRoomSummaryPlaceholders {
|
||||
|
||||
fun create(id: String): RoomListRoomSummary {
|
||||
|
|
@ -23,6 +22,4 @@ object RoomListRoomSummaryPlaceholders {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
package io.element.android.x.features.roomlist.model
|
||||
|
||||
import io.element.android.x.designsystem.components.avatar.AvatarData
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
internal fun stubbedRoomSummaries(): List<RoomListRoomSummary> {
|
||||
return listOf(
|
||||
internal fun stubbedRoomSummaries(): ImmutableList<RoomListRoomSummary> {
|
||||
return persistentListOf(
|
||||
RoomListRoomSummary(
|
||||
name = "Room",
|
||||
hasUnread = true,
|
||||
|
|
@ -22,4 +24,4 @@ internal fun stubbedRoomSummaries(): List<RoomListRoomSummary> {
|
|||
),
|
||||
RoomListRoomSummaryPlaceholders.create("roomId2")
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
package io.element.android.x.features.roomlist
|
||||
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
|
|
@ -14,4 +13,4 @@ class ExampleUnitTest {
|
|||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@ kotlin.code.style=official
|
|||
# resources declared in the library itself and none from the library's dependencies,
|
||||
# thereby reducing the size of the R class for that library
|
||||
android.nonTransitiveRClass=true
|
||||
|
||||
# Dummy values for signing secrets / nightly
|
||||
signing.element.nightly.storePassword=Secret
|
||||
signing.element.nightly.keyId=Secret
|
||||
signing.element.nightly.keyPassword=Secret
|
||||
signing.element.nightly.keyPassword=Secret
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
# This file is referenced in ./plugins/settings.gradle.kts to generate the version catalog.
|
||||
# https://docs.gradle.org/current/userguide/platforms.html#sub::toml-dependencies-format
|
||||
|
||||
[versions]
|
||||
# Project
|
||||
android_gradle_plugin = "7.3.1"
|
||||
|
|
@ -39,7 +42,6 @@ test_orchestrator = "1.4.1"
|
|||
|
||||
#other
|
||||
mavericks = "3.0.1"
|
||||
timber = "5.0.1"
|
||||
coil = "2.2.1"
|
||||
datetime = "0.4.0"
|
||||
wysiwyg = "0.7.0.1"
|
||||
|
|
@ -52,6 +54,10 @@ jsoup = "1.15.3"
|
|||
dagger = "2.43"
|
||||
anvil = "2.4.2"
|
||||
|
||||
# quality
|
||||
detekt = "1.22.0"
|
||||
ktlint = "11.0.0"
|
||||
|
||||
[libraries]
|
||||
# Project
|
||||
android_gradle_plugin = { module = "com.android.tools.build:gradle", version.ref = "android_gradle_plugin" }
|
||||
|
|
@ -102,13 +108,12 @@ test_orchestrator = { module = "androidx.test:orchestrator", version.ref = "test
|
|||
|
||||
# Others
|
||||
mavericks_compose = { module = "com.airbnb.android:mavericks-compose", version.ref = "mavericks" }
|
||||
timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" }
|
||||
coil = { module = "io.coil-kt:coil", version.ref = "coil" }
|
||||
coil_compose = { module = "io.coil-kt:coil-compose", version.ref = "coil" }
|
||||
datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "datetime" }
|
||||
serialization_json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "serialization_json" }
|
||||
compose_destinations = { module = "io.github.raamcosta.compose-destinations:animations-core", version.ref = "compose_destinations" }
|
||||
compose_destinations_processor = {module = "io.github.raamcosta.compose-destinations:ksp", version.ref = "compose_destinations"}
|
||||
compose_destinations_processor = { module = "io.github.raamcosta.compose-destinations:ksp", version.ref = "compose_destinations" }
|
||||
showkase = { module = "com.airbnb.android:showkase", version.ref = "showkase" }
|
||||
showkase_processor = { module = "com.airbnb.android:showkase-processor", version.ref = "showkase" }
|
||||
jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoup" }
|
||||
|
|
@ -133,4 +138,6 @@ kotlin_android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
|
|||
kotlin_jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
|
||||
kapt = {id = "org.jetbrains.kotlin.kapt", version.ref = "kotlin"}
|
||||
ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" }
|
||||
anvil = {id = "com.squareup.anvil", version.ref = "anvil"}
|
||||
anvil = {id = "com.squareup.anvil", version.ref = "anvil"}
|
||||
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
|
||||
ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" }
|
||||
|
|
|
|||
|
|
@ -1,22 +1,21 @@
|
|||
package io.element.android.x.core.compose
|
||||
|
||||
import android.util.Log
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.SideEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import io.element.android.x.core.BuildConfig
|
||||
|
||||
import timber.log.Timber
|
||||
|
||||
// Note the inline function below which ensures that this function is essentially
|
||||
// copied at the call site to ensure that its logging only recompositions from the
|
||||
// original call site.
|
||||
@Composable
|
||||
inline fun LogCompositions(tag: String, msg: String) {
|
||||
fun LogCompositions(tag: String, msg: String) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
val ref = remember { Ref(0) }
|
||||
SideEffect { ref.value++ }
|
||||
Log.d(tag, "Compositions: $msg ${ref.value}")
|
||||
Timber.d(tag, "Compositions: $msg ${ref.value}")
|
||||
}
|
||||
}
|
||||
|
||||
class Ref(var value: Int)
|
||||
class Ref(var value: Int)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import androidx.lifecycle.LifecycleOwner
|
|||
fun OnLifecycleEvent(onEvent: (owner: LifecycleOwner, event: Lifecycle.Event) -> Unit) {
|
||||
val eventHandler = rememberUpdatedState(onEvent)
|
||||
val lifecycleOwner = rememberUpdatedState(LocalLifecycleOwner.current)
|
||||
|
||||
|
||||
DisposableEffect(lifecycleOwner.value) {
|
||||
val lifecycle = lifecycleOwner.value.lifecycle
|
||||
val observer = LifecycleEventObserver { owner, event ->
|
||||
|
|
@ -24,4 +24,4 @@ fun OnLifecycleEvent(onEvent: (owner: LifecycleOwner, event: Lifecycle.Event) ->
|
|||
lifecycle.removeObserver(observer)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ import androidx.compose.runtime.MutableState
|
|||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
|
||||
|
||||
@Composable
|
||||
public fun textFieldState(stateValue: String): MutableState<String> =
|
||||
remember(stateValue) { mutableStateOf(stateValue) }
|
||||
remember(stateValue) { mutableStateOf(stateValue) }
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package io.element.android.x.core.data.flow
|
||||
package io.element.android.x.core.coroutine
|
||||
|
||||
import android.os.SystemClock
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
package io.element.android.x.core.data
|
||||
package io.element.android.x.core.coroutine
|
||||
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.awaitAll
|
||||
|
|
@ -7,4 +7,4 @@ import kotlinx.coroutines.coroutineScope
|
|||
// https://jivimberg.io/blog/2018/05/04/parallel-map-in-kotlin/
|
||||
suspend fun <A, B> Iterable<A>.parallelMap(f: suspend (A) -> B): List<B> = coroutineScope {
|
||||
map { async { f(it) } }.awaitAll()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,13 @@
|
|||
package io.element.android.x.core.data
|
||||
|
||||
import android.util.Log
|
||||
import timber.log.Timber
|
||||
|
||||
inline fun <A> tryOrNull(message: String? = null, operation: () -> A): A? {
|
||||
return try {
|
||||
operation()
|
||||
} catch (any: Throwable) {
|
||||
if (message != null) {
|
||||
Log.e("TAG", message, any)
|
||||
Timber.e("TAG", message, any)
|
||||
}
|
||||
null
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,18 +24,18 @@ class DimensionConverter(val resources: Resources) {
|
|||
@Px
|
||||
fun dpToPx(dp: Int): Int {
|
||||
return TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
dp.toFloat(),
|
||||
resources.displayMetrics
|
||||
TypedValue.COMPLEX_UNIT_DIP,
|
||||
dp.toFloat(),
|
||||
resources.displayMetrics
|
||||
).toInt()
|
||||
}
|
||||
|
||||
@Px
|
||||
fun spToPx(sp: Int): Int {
|
||||
return TypedValue.applyDimension(
|
||||
TypedValue.COMPLEX_UNIT_SP,
|
||||
sp.toFloat(),
|
||||
resources.displayMetrics
|
||||
TypedValue.COMPLEX_UNIT_SP,
|
||||
sp.toFloat(),
|
||||
resources.displayMetrics
|
||||
).toInt()
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -35,9 +35,9 @@ fun View.showKeyboard(andRequestFocus: Boolean = false) {
|
|||
|
||||
fun View.setHorizontalPadding(padding: Int) {
|
||||
setPadding(
|
||||
padding,
|
||||
paddingTop,
|
||||
padding,
|
||||
paddingBottom
|
||||
padding,
|
||||
paddingTop,
|
||||
padding,
|
||||
paddingBottom
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue