Refactoring using eslint & prettier

This commit is contained in:
obergodmar
2020-08-19 14:58:49 +03:00
parent 3868d89571
commit 26e9c3afaa
67 changed files with 2068 additions and 2502 deletions
-634
View File
@@ -1,634 +0,0 @@
[*]
charset = utf-8
end_of_line = crlf
indent_size = 4
indent_style = space
insert_final_newline = true
max_line_length = 120
tab_width = 4
trim_trailing_whitespace = true
ij_continuation_indent_size = 8
ij_formatter_off_tag = @formatter:off
ij_formatter_on_tag = @formatter:on
ij_formatter_tags_enabled = false
ij_smart_tabs = false
ij_wrap_on_typing = false
[*.css]
ij_css_align_closing_brace_with_properties = false
ij_css_blank_lines_around_nested_selector = 1
ij_css_blank_lines_between_blocks = 1
ij_css_brace_placement = end_of_line
ij_css_enforce_quotes_on_format = false
ij_css_hex_color_long_format = false
ij_css_hex_color_lower_case = false
ij_css_hex_color_short_format = false
ij_css_hex_color_upper_case = false
ij_css_keep_blank_lines_in_code = 2
ij_css_keep_indents_on_empty_lines = false
ij_css_keep_single_line_blocks = false
ij_css_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
ij_css_space_after_colon = true
ij_css_space_before_opening_brace = true
ij_css_use_double_quotes = true
ij_css_value_alignment = do_not_align
[*.feature]
indent_size = 2
ij_gherkin_keep_indents_on_empty_lines = false
[*.haml]
indent_size = 2
ij_haml_keep_indents_on_empty_lines = false
[*.less]
indent_size = 2
ij_less_align_closing_brace_with_properties = false
ij_less_blank_lines_around_nested_selector = 1
ij_less_blank_lines_between_blocks = 1
ij_less_brace_placement = 0
ij_less_enforce_quotes_on_format = false
ij_less_hex_color_long_format = false
ij_less_hex_color_lower_case = false
ij_less_hex_color_short_format = false
ij_less_hex_color_upper_case = false
ij_less_keep_blank_lines_in_code = 2
ij_less_keep_indents_on_empty_lines = false
ij_less_keep_single_line_blocks = false
ij_less_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
ij_less_space_after_colon = true
ij_less_space_before_opening_brace = true
ij_less_use_double_quotes = true
ij_less_value_alignment = 0
[*.sass]
indent_size = 2
ij_sass_align_closing_brace_with_properties = false
ij_sass_blank_lines_around_nested_selector = 1
ij_sass_blank_lines_between_blocks = 1
ij_sass_brace_placement = 0
ij_sass_enforce_quotes_on_format = false
ij_sass_hex_color_long_format = false
ij_sass_hex_color_lower_case = false
ij_sass_hex_color_short_format = false
ij_sass_hex_color_upper_case = false
ij_sass_keep_blank_lines_in_code = 2
ij_sass_keep_indents_on_empty_lines = false
ij_sass_keep_single_line_blocks = false
ij_sass_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
ij_sass_space_after_colon = true
ij_sass_space_before_opening_brace = true
ij_sass_use_double_quotes = true
ij_sass_value_alignment = 0
[*.scss]
indent_size = 2
ij_scss_align_closing_brace_with_properties = false
ij_scss_blank_lines_around_nested_selector = 1
ij_scss_blank_lines_between_blocks = 1
ij_scss_brace_placement = 0
ij_scss_enforce_quotes_on_format = false
ij_scss_hex_color_long_format = false
ij_scss_hex_color_lower_case = false
ij_scss_hex_color_short_format = false
ij_scss_hex_color_upper_case = false
ij_scss_keep_blank_lines_in_code = 2
ij_scss_keep_indents_on_empty_lines = false
ij_scss_keep_single_line_blocks = false
ij_scss_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
ij_scss_space_after_colon = true
ij_scss_space_before_opening_brace = true
ij_scss_use_double_quotes = true
ij_scss_value_alignment = 0
[*.styl]
indent_size = 2
ij_stylus_align_closing_brace_with_properties = false
ij_stylus_blank_lines_around_nested_selector = 1
ij_stylus_blank_lines_between_blocks = 1
ij_stylus_brace_placement = 0
ij_stylus_enforce_quotes_on_format = false
ij_stylus_hex_color_long_format = false
ij_stylus_hex_color_lower_case = false
ij_stylus_hex_color_short_format = false
ij_stylus_hex_color_upper_case = false
ij_stylus_keep_blank_lines_in_code = 2
ij_stylus_keep_indents_on_empty_lines = false
ij_stylus_keep_single_line_blocks = false
ij_stylus_properties_order = font, font-family, font-size, font-weight, font-style, font-variant, font-size-adjust, font-stretch, line-height, position, z-index, top, right, bottom, left, display, visibility, float, clear, overflow, overflow-x, overflow-y, clip, zoom, align-content, align-items, align-self, flex, flex-flow, flex-basis, flex-direction, flex-grow, flex-shrink, flex-wrap, justify-content, order, box-sizing, width, min-width, max-width, height, min-height, max-height, margin, margin-top, margin-right, margin-bottom, margin-left, padding, padding-top, padding-right, padding-bottom, padding-left, table-layout, empty-cells, caption-side, border-spacing, border-collapse, list-style, list-style-position, list-style-type, list-style-image, content, quotes, counter-reset, counter-increment, resize, cursor, user-select, nav-index, nav-up, nav-right, nav-down, nav-left, transition, transition-delay, transition-timing-function, transition-duration, transition-property, transform, transform-origin, animation, animation-name, animation-duration, animation-play-state, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, text-align, text-align-last, vertical-align, white-space, text-decoration, text-emphasis, text-emphasis-color, text-emphasis-style, text-emphasis-position, text-indent, text-justify, letter-spacing, word-spacing, text-outline, text-transform, text-wrap, text-overflow, text-overflow-ellipsis, text-overflow-mode, word-wrap, word-break, tab-size, hyphens, pointer-events, opacity, color, border, border-width, border-style, border-color, border-top, border-top-width, border-top-style, border-top-color, border-right, border-right-width, border-right-style, border-right-color, border-bottom, border-bottom-width, border-bottom-style, border-bottom-color, border-left, border-left-width, border-left-style, border-left-color, border-radius, border-top-left-radius, border-top-right-radius, border-bottom-right-radius, border-bottom-left-radius, border-image, border-image-source, border-image-slice, border-image-width, border-image-outset, border-image-repeat, outline, outline-width, outline-style, outline-color, outline-offset, background, background-color, background-image, background-repeat, background-attachment, background-position, background-position-x, background-position-y, background-clip, background-origin, background-size, box-decoration-break, box-shadow, text-shadow
ij_stylus_space_after_colon = true
ij_stylus_space_before_opening_brace = true
ij_stylus_use_double_quotes = true
ij_stylus_value_alignment = 0
[.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_xml_align_attributes = true
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 = true
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 = false
ij_xml_text_wrap = normal
[{*.ats, *.ts}]
indent_style = tab
ij_continuation_indent_size = 4
ij_smart_tabs = true
ij_typescript_align_imports = false
ij_typescript_align_multiline_array_initializer_expression = false
ij_typescript_align_multiline_binary_operation = false
ij_typescript_align_multiline_chained_methods = false
ij_typescript_align_multiline_extends_list = false
ij_typescript_align_multiline_for = true
ij_typescript_align_multiline_parameters = true
ij_typescript_align_multiline_parameters_in_calls = false
ij_typescript_align_multiline_ternary_operation = false
ij_typescript_align_object_properties = 0
ij_typescript_align_union_types = false
ij_typescript_align_var_statements = 0
ij_typescript_array_initializer_new_line_after_left_brace = false
ij_typescript_array_initializer_right_brace_on_new_line = false
ij_typescript_array_initializer_wrap = off
ij_typescript_assignment_wrap = off
ij_typescript_binary_operation_sign_on_next_line = false
ij_typescript_binary_operation_wrap = off
ij_typescript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**
ij_typescript_blank_lines_after_imports = 1
ij_typescript_blank_lines_around_class = 1
ij_typescript_blank_lines_around_field = 0
ij_typescript_blank_lines_around_field_in_interface = 0
ij_typescript_blank_lines_around_function = 1
ij_typescript_blank_lines_around_method = 1
ij_typescript_blank_lines_around_method_in_interface = 1
ij_typescript_block_brace_style = end_of_line
ij_typescript_call_parameters_new_line_after_left_paren = false
ij_typescript_call_parameters_right_paren_on_new_line = false
ij_typescript_call_parameters_wrap = off
ij_typescript_catch_on_new_line = false
ij_typescript_chained_call_dot_on_new_line = true
ij_typescript_class_brace_style = end_of_line
ij_typescript_comma_on_new_line = false
ij_typescript_do_while_brace_force = never
ij_typescript_else_on_new_line = false
ij_typescript_enforce_trailing_comma = remove
ij_typescript_extends_keyword_wrap = off
ij_typescript_extends_list_wrap = off
ij_typescript_field_prefix = _
ij_typescript_file_name_style = relaxed
ij_typescript_finally_on_new_line = false
ij_typescript_for_brace_force = never
ij_typescript_for_statement_new_line_after_left_paren = false
ij_typescript_for_statement_right_paren_on_new_line = false
ij_typescript_for_statement_wrap = off
ij_typescript_force_quote_style = true
ij_typescript_force_semicolon_style = true
ij_typescript_function_expression_brace_style = end_of_line
ij_typescript_if_brace_force = never
ij_typescript_import_merge_members = global
ij_typescript_import_prefer_absolute_path = global
ij_typescript_import_sort_members = true
ij_typescript_import_sort_module_name = false
ij_typescript_import_use_node_resolution = true
ij_typescript_imports_wrap = on_every_item
ij_typescript_indent_case_from_switch = true
ij_typescript_indent_chained_calls = true
ij_typescript_indent_package_children = 0
ij_typescript_jsdoc_include_types = false
ij_typescript_jsx_attribute_value = braces
ij_typescript_keep_blank_lines_in_code = 1
ij_typescript_keep_first_column_comment = true
ij_typescript_keep_indents_on_empty_lines = false
ij_typescript_keep_line_breaks = true
ij_typescript_keep_simple_blocks_in_one_line = false
ij_typescript_keep_simple_methods_in_one_line = false
ij_typescript_line_comment_add_space = true
ij_typescript_line_comment_at_first_column = false
ij_typescript_method_brace_style = end_of_line
ij_typescript_method_call_chain_wrap = off
ij_typescript_method_parameters_new_line_after_left_paren = false
ij_typescript_method_parameters_right_paren_on_new_line = false
ij_typescript_method_parameters_wrap = off
ij_typescript_object_literal_wrap = on_every_item
ij_typescript_parentheses_expression_new_line_after_left_paren = false
ij_typescript_parentheses_expression_right_paren_on_new_line = false
ij_typescript_place_assignment_sign_on_next_line = false
ij_typescript_prefer_as_type_cast = false
ij_typescript_prefer_explicit_types_function_expression_returns = false
ij_typescript_prefer_explicit_types_function_returns = false
ij_typescript_prefer_explicit_types_vars_fields = false
ij_typescript_prefer_parameters_wrap = false
ij_typescript_reformat_c_style_comments = false
ij_typescript_space_after_colon = true
ij_typescript_space_after_comma = true
ij_typescript_space_after_dots_in_rest_parameter = false
ij_typescript_space_after_generator_mult = true
ij_typescript_space_after_property_colon = true
ij_typescript_space_after_quest = true
ij_typescript_space_after_type_colon = true
ij_typescript_space_after_unary_not = false
ij_typescript_space_before_async_arrow_lparen = true
ij_typescript_space_before_catch_keyword = true
ij_typescript_space_before_catch_left_brace = true
ij_typescript_space_before_catch_parentheses = true
ij_typescript_space_before_class_lbrace = true
ij_typescript_space_before_class_left_brace = true
ij_typescript_space_before_colon = true
ij_typescript_space_before_comma = false
ij_typescript_space_before_do_left_brace = true
ij_typescript_space_before_else_keyword = true
ij_typescript_space_before_else_left_brace = true
ij_typescript_space_before_finally_keyword = true
ij_typescript_space_before_finally_left_brace = true
ij_typescript_space_before_for_left_brace = true
ij_typescript_space_before_for_parentheses = true
ij_typescript_space_before_for_semicolon = false
ij_typescript_space_before_function_left_parenth = true
ij_typescript_space_before_generator_mult = false
ij_typescript_space_before_if_left_brace = true
ij_typescript_space_before_if_parentheses = true
ij_typescript_space_before_method_call_parentheses = false
ij_typescript_space_before_method_left_brace = true
ij_typescript_space_before_method_parentheses = false
ij_typescript_space_before_property_colon = false
ij_typescript_space_before_quest = true
ij_typescript_space_before_switch_left_brace = true
ij_typescript_space_before_switch_parentheses = true
ij_typescript_space_before_try_left_brace = true
ij_typescript_space_before_type_colon = false
ij_typescript_space_before_unary_not = false
ij_typescript_space_before_while_keyword = true
ij_typescript_space_before_while_left_brace = true
ij_typescript_space_before_while_parentheses = true
ij_typescript_spaces_around_additive_operators = true
ij_typescript_spaces_around_arrow_function_operator = true
ij_typescript_spaces_around_assignment_operators = true
ij_typescript_spaces_around_bitwise_operators = true
ij_typescript_spaces_around_equality_operators = true
ij_typescript_spaces_around_logical_operators = true
ij_typescript_spaces_around_multiplicative_operators = true
ij_typescript_spaces_around_relational_operators = true
ij_typescript_spaces_around_shift_operators = true
ij_typescript_spaces_around_unary_operator = false
ij_typescript_spaces_within_array_initializer_brackets = false
ij_typescript_spaces_within_brackets = false
ij_typescript_spaces_within_catch_parentheses = false
ij_typescript_spaces_within_for_parentheses = false
ij_typescript_spaces_within_if_parentheses = false
ij_typescript_spaces_within_imports = true
ij_typescript_spaces_within_interpolation_expressions = false
ij_typescript_spaces_within_method_call_parentheses = false
ij_typescript_spaces_within_method_parentheses = false
ij_typescript_spaces_within_object_literal_braces = true
ij_typescript_spaces_within_object_type_braces = true
ij_typescript_spaces_within_parentheses = false
ij_typescript_spaces_within_switch_parentheses = false
ij_typescript_spaces_within_type_assertion = false
ij_typescript_spaces_within_union_types = true
ij_typescript_spaces_within_while_parentheses = false
ij_typescript_special_else_if_treatment = true
ij_typescript_ternary_operation_signs_on_next_line = false
ij_typescript_ternary_operation_wrap = off
ij_typescript_union_types_wrap = on_every_item
ij_typescript_use_chained_calls_group_indents = false
ij_typescript_use_double_quotes = false
ij_typescript_use_explicit_js_extension = global
ij_typescript_use_path_mapping = always
ij_typescript_use_public_modifier = false
ij_typescript_use_semicolon_after_statement = false
ij_typescript_var_declaration_wrap = normal
ij_typescript_while_brace_force = never
ij_typescript_while_on_new_line = false
ij_typescript_wrap_comments = false
[{*.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
[{*.cjs, *.js}]
ij_continuation_indent_size = 4
ij_javascript_align_imports = false
ij_javascript_align_multiline_array_initializer_expression = false
ij_javascript_align_multiline_binary_operation = false
ij_javascript_align_multiline_chained_methods = false
ij_javascript_align_multiline_extends_list = false
ij_javascript_align_multiline_for = true
ij_javascript_align_multiline_parameters = true
ij_javascript_align_multiline_parameters_in_calls = false
ij_javascript_align_multiline_ternary_operation = false
ij_javascript_align_object_properties = 0
ij_javascript_align_union_types = false
ij_javascript_align_var_statements = 0
ij_javascript_array_initializer_new_line_after_left_brace = false
ij_javascript_array_initializer_right_brace_on_new_line = false
ij_javascript_array_initializer_wrap = off
ij_javascript_assignment_wrap = off
ij_javascript_binary_operation_sign_on_next_line = false
ij_javascript_binary_operation_wrap = off
ij_javascript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**
ij_javascript_blank_lines_after_imports = 1
ij_javascript_blank_lines_around_class = 1
ij_javascript_blank_lines_around_field = 0
ij_javascript_blank_lines_around_function = 1
ij_javascript_blank_lines_around_method = 1
ij_javascript_block_brace_style = end_of_line
ij_javascript_call_parameters_new_line_after_left_paren = false
ij_javascript_call_parameters_right_paren_on_new_line = false
ij_javascript_call_parameters_wrap = off
ij_javascript_catch_on_new_line = false
ij_javascript_chained_call_dot_on_new_line = true
ij_javascript_class_brace_style = end_of_line
ij_javascript_comma_on_new_line = false
ij_javascript_do_while_brace_force = never
ij_javascript_else_on_new_line = false
ij_javascript_enforce_trailing_comma = keep
ij_javascript_extends_keyword_wrap = off
ij_javascript_extends_list_wrap = off
ij_javascript_field_prefix = _
ij_javascript_file_name_style = relaxed
ij_javascript_finally_on_new_line = false
ij_javascript_for_brace_force = never
ij_javascript_for_statement_new_line_after_left_paren = false
ij_javascript_for_statement_right_paren_on_new_line = false
ij_javascript_for_statement_wrap = off
ij_javascript_force_quote_style = false
ij_javascript_force_semicolon_style = false
ij_javascript_function_expression_brace_style = end_of_line
ij_javascript_if_brace_force = never
ij_javascript_import_merge_members = global
ij_javascript_import_prefer_absolute_path = global
ij_javascript_import_sort_members = true
ij_javascript_import_sort_module_name = false
ij_javascript_import_use_node_resolution = true
ij_javascript_imports_wrap = on_every_item
ij_javascript_indent_case_from_switch = true
ij_javascript_indent_chained_calls = true
ij_javascript_indent_package_children = 0
ij_javascript_jsx_attribute_value = braces
ij_javascript_keep_blank_lines_in_code = 2
ij_javascript_keep_first_column_comment = true
ij_javascript_keep_indents_on_empty_lines = false
ij_javascript_keep_line_breaks = true
ij_javascript_keep_simple_blocks_in_one_line = false
ij_javascript_keep_simple_methods_in_one_line = false
ij_javascript_line_comment_add_space = true
ij_javascript_line_comment_at_first_column = false
ij_javascript_method_brace_style = end_of_line
ij_javascript_method_call_chain_wrap = off
ij_javascript_method_parameters_new_line_after_left_paren = false
ij_javascript_method_parameters_right_paren_on_new_line = false
ij_javascript_method_parameters_wrap = off
ij_javascript_object_literal_wrap = on_every_item
ij_javascript_parentheses_expression_new_line_after_left_paren = false
ij_javascript_parentheses_expression_right_paren_on_new_line = false
ij_javascript_place_assignment_sign_on_next_line = false
ij_javascript_prefer_as_type_cast = false
ij_javascript_prefer_explicit_types_function_expression_returns = false
ij_javascript_prefer_explicit_types_function_returns = false
ij_javascript_prefer_explicit_types_vars_fields = false
ij_javascript_prefer_parameters_wrap = false
ij_javascript_reformat_c_style_comments = false
ij_javascript_space_after_colon = true
ij_javascript_space_after_comma = true
ij_javascript_space_after_dots_in_rest_parameter = false
ij_javascript_space_after_generator_mult = true
ij_javascript_space_after_property_colon = true
ij_javascript_space_after_quest = true
ij_javascript_space_after_type_colon = true
ij_javascript_space_after_unary_not = false
ij_javascript_space_before_async_arrow_lparen = true
ij_javascript_space_before_catch_keyword = true
ij_javascript_space_before_catch_left_brace = true
ij_javascript_space_before_catch_parentheses = true
ij_javascript_space_before_class_lbrace = true
ij_javascript_space_before_class_left_brace = true
ij_javascript_space_before_colon = true
ij_javascript_space_before_comma = false
ij_javascript_space_before_do_left_brace = true
ij_javascript_space_before_else_keyword = true
ij_javascript_space_before_else_left_brace = true
ij_javascript_space_before_finally_keyword = true
ij_javascript_space_before_finally_left_brace = true
ij_javascript_space_before_for_left_brace = true
ij_javascript_space_before_for_parentheses = true
ij_javascript_space_before_for_semicolon = false
ij_javascript_space_before_function_left_parenth = true
ij_javascript_space_before_generator_mult = false
ij_javascript_space_before_if_left_brace = true
ij_javascript_space_before_if_parentheses = true
ij_javascript_space_before_method_call_parentheses = false
ij_javascript_space_before_method_left_brace = true
ij_javascript_space_before_method_parentheses = false
ij_javascript_space_before_property_colon = false
ij_javascript_space_before_quest = true
ij_javascript_space_before_switch_left_brace = true
ij_javascript_space_before_switch_parentheses = true
ij_javascript_space_before_try_left_brace = true
ij_javascript_space_before_type_colon = false
ij_javascript_space_before_unary_not = false
ij_javascript_space_before_while_keyword = true
ij_javascript_space_before_while_left_brace = true
ij_javascript_space_before_while_parentheses = true
ij_javascript_spaces_around_additive_operators = true
ij_javascript_spaces_around_arrow_function_operator = true
ij_javascript_spaces_around_assignment_operators = true
ij_javascript_spaces_around_bitwise_operators = true
ij_javascript_spaces_around_equality_operators = true
ij_javascript_spaces_around_logical_operators = true
ij_javascript_spaces_around_multiplicative_operators = true
ij_javascript_spaces_around_relational_operators = true
ij_javascript_spaces_around_shift_operators = true
ij_javascript_spaces_around_unary_operator = false
ij_javascript_spaces_within_array_initializer_brackets = false
ij_javascript_spaces_within_brackets = false
ij_javascript_spaces_within_catch_parentheses = false
ij_javascript_spaces_within_for_parentheses = false
ij_javascript_spaces_within_if_parentheses = false
ij_javascript_spaces_within_imports = false
ij_javascript_spaces_within_interpolation_expressions = false
ij_javascript_spaces_within_method_call_parentheses = false
ij_javascript_spaces_within_method_parentheses = false
ij_javascript_spaces_within_object_literal_braces = false
ij_javascript_spaces_within_object_type_braces = true
ij_javascript_spaces_within_parentheses = false
ij_javascript_spaces_within_switch_parentheses = false
ij_javascript_spaces_within_type_assertion = false
ij_javascript_spaces_within_union_types = true
ij_javascript_spaces_within_while_parentheses = false
ij_javascript_special_else_if_treatment = true
ij_javascript_ternary_operation_signs_on_next_line = false
ij_javascript_ternary_operation_wrap = off
ij_javascript_union_types_wrap = on_every_item
ij_javascript_use_chained_calls_group_indents = false
ij_javascript_use_double_quotes = true
ij_javascript_use_explicit_js_extension = global
ij_javascript_use_path_mapping = always
ij_javascript_use_public_modifier = false
ij_javascript_use_semicolon_after_statement = true
ij_javascript_var_declaration_wrap = normal
ij_javascript_while_brace_force = never
ij_javascript_while_on_new_line = false
ij_javascript_wrap_comments = false
[{*.cjsx, *.coffee}]
indent_size = 2
tab_width = 2
ij_continuation_indent_size = 2
ij_coffeescript_align_function_body = false
ij_coffeescript_align_imports = false
ij_coffeescript_align_multiline_array_initializer_expression = true
ij_coffeescript_align_multiline_parameters = true
ij_coffeescript_align_multiline_parameters_in_calls = false
ij_coffeescript_align_object_properties = 0
ij_coffeescript_align_union_types = false
ij_coffeescript_align_var_statements = 0
ij_coffeescript_array_initializer_new_line_after_left_brace = false
ij_coffeescript_array_initializer_right_brace_on_new_line = false
ij_coffeescript_array_initializer_wrap = normal
ij_coffeescript_blacklist_imports = rxjs/Rx, node_modules/**, **/node_modules/**, @angular/material, @angular/material/typings/**
ij_coffeescript_blank_lines_around_function = 1
ij_coffeescript_call_parameters_new_line_after_left_paren = false
ij_coffeescript_call_parameters_right_paren_on_new_line = false
ij_coffeescript_call_parameters_wrap = normal
ij_coffeescript_chained_call_dot_on_new_line = true
ij_coffeescript_comma_on_new_line = false
ij_coffeescript_enforce_trailing_comma = keep
ij_coffeescript_field_prefix = _
ij_coffeescript_file_name_style = relaxed
ij_coffeescript_force_quote_style = false
ij_coffeescript_force_semicolon_style = false
ij_coffeescript_function_expression_brace_style = end_of_line
ij_coffeescript_import_merge_members = global
ij_coffeescript_import_prefer_absolute_path = global
ij_coffeescript_import_sort_members = true
ij_coffeescript_import_sort_module_name = false
ij_coffeescript_import_use_node_resolution = true
ij_coffeescript_imports_wrap = on_every_item
ij_coffeescript_indent_chained_calls = true
ij_coffeescript_indent_package_children = 0
ij_coffeescript_jsx_attribute_value = braces
ij_coffeescript_keep_blank_lines_in_code = 2
ij_coffeescript_keep_first_column_comment = true
ij_coffeescript_keep_indents_on_empty_lines = false
ij_coffeescript_keep_line_breaks = true
ij_coffeescript_keep_simple_methods_in_one_line = false
ij_coffeescript_method_parameters_new_line_after_left_paren = false
ij_coffeescript_method_parameters_right_paren_on_new_line = false
ij_coffeescript_method_parameters_wrap = off
ij_coffeescript_object_literal_wrap = on_every_item
ij_coffeescript_prefer_as_type_cast = false
ij_coffeescript_prefer_explicit_types_function_expression_returns = false
ij_coffeescript_prefer_explicit_types_function_returns = false
ij_coffeescript_prefer_explicit_types_vars_fields = false
ij_coffeescript_reformat_c_style_comments = false
ij_coffeescript_space_after_comma = true
ij_coffeescript_space_after_dots_in_rest_parameter = false
ij_coffeescript_space_after_generator_mult = true
ij_coffeescript_space_after_property_colon = true
ij_coffeescript_space_after_type_colon = true
ij_coffeescript_space_after_unary_not = false
ij_coffeescript_space_before_async_arrow_lparen = true
ij_coffeescript_space_before_class_lbrace = true
ij_coffeescript_space_before_comma = false
ij_coffeescript_space_before_function_left_parenth = true
ij_coffeescript_space_before_generator_mult = false
ij_coffeescript_space_before_property_colon = false
ij_coffeescript_space_before_type_colon = false
ij_coffeescript_space_before_unary_not = false
ij_coffeescript_spaces_around_additive_operators = true
ij_coffeescript_spaces_around_arrow_function_operator = true
ij_coffeescript_spaces_around_assignment_operators = true
ij_coffeescript_spaces_around_bitwise_operators = true
ij_coffeescript_spaces_around_equality_operators = true
ij_coffeescript_spaces_around_logical_operators = true
ij_coffeescript_spaces_around_multiplicative_operators = true
ij_coffeescript_spaces_around_relational_operators = true
ij_coffeescript_spaces_around_shift_operators = true
ij_coffeescript_spaces_around_unary_operator = false
ij_coffeescript_spaces_within_array_initializer_braces = false
ij_coffeescript_spaces_within_array_initializer_brackets = false
ij_coffeescript_spaces_within_imports = false
ij_coffeescript_spaces_within_index_brackets = false
ij_coffeescript_spaces_within_interpolation_expressions = false
ij_coffeescript_spaces_within_method_call_parentheses = false
ij_coffeescript_spaces_within_method_parentheses = false
ij_coffeescript_spaces_within_object_braces = false
ij_coffeescript_spaces_within_object_literal_braces = false
ij_coffeescript_spaces_within_object_type_braces = true
ij_coffeescript_spaces_within_range_brackets = false
ij_coffeescript_spaces_within_type_assertion = false
ij_coffeescript_spaces_within_union_types = true
ij_coffeescript_union_types_wrap = on_every_item
ij_coffeescript_use_chained_calls_group_indents = false
ij_coffeescript_use_double_quotes = true
ij_coffeescript_use_explicit_js_extension = global
ij_coffeescript_use_path_mapping = always
ij_coffeescript_use_public_modifier = false
ij_coffeescript_use_semicolon_after_statement = false
ij_coffeescript_var_declaration_wrap = normal
[{*.har, *.jsb2, *.jsb3, *.json, .babelrc, .eslintrc, .prettierrc, .stylelintrc, bowerrc, jest.config}]
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, *.ng, *.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
[{*.yaml, *.yml}]
indent_size = 2
ij_yaml_keep_indents_on_empty_lines = false
ij_yaml_keep_line_breaks = true
+2
View File
@@ -0,0 +1,2 @@
build
coverage
+57
View File
@@ -0,0 +1,57 @@
module.exports = {
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: 2020,
sourceType: "module",
ecmaFeatures: {
jsx: true,
},
},
extends: [
"plugin:@typescript-eslint/recommended",
"airbnb-base",
"airbnb/hooks",
"prettier",
"prettier/@typescript-eslint",
"plugin:react/recommended",
"plugin:prettier/recommended",
"plugin:jest/recommended",
],
plugins: ["react", "import", "jest", "jsx-a11y", "prettier"],
env: {
browser: true,
es6: true,
},
globals: {
Atomics: "readonly",
SharedArrayBuffer: "readonly",
},
settings: {
react: {
version: "detect",
},
},
rules: {
"import/no-extraneous-dependencies": [
"warn",
{
devDependencies: ["**/*.test.js", "**/*.test.jsx", "**/setup-tests.js"],
},
],
"linebreak-style": "off",
"import/extensions": "off",
"import/no-unresolved": "off",
"import/prefer-default-export": "off",
"prettier/prettier": [
"error",
{
endOfLine: "auto",
},
],
"jest/no-disabled-tests": "warn",
"jest/no-focused-tests": "error",
"jest/no-identical-title": "error",
"jest/prefer-to-have-length": "warn",
"jest/valid-expect": "error",
},
};
+1
View File
@@ -3,3 +3,4 @@ package-lock.json
build
.idea
.firebase
yarn.lock
+1
View File
@@ -0,0 +1 @@
registry=https://registry.npmjs.com/
+2
View File
@@ -0,0 +1,2 @@
build
coverage
+16
View File
@@ -0,0 +1,16 @@
module.exports = {
extends: [
"stylelint-config-recommended-scss",
"stylelint-config-standard",
"stylelint-config-rational-order",
],
rules: {
indentation: 4,
"rule-empty-line-before": null,
"at-rule-empty-line-before": null,
"declaration-empty-line-before": null,
"no-descending-specificity": null,
"number-leading-zero": "never",
"string-quotes": "double",
},
};
+38 -2
View File
@@ -2,11 +2,15 @@
"name": "wow-best-places",
"description": "This app is supposed to make you feel nostalgic",
"version": "1.3.1",
"license": "MIT",
"author": {
"name": "obergodmar",
"email": "obergodmar@gmail.com",
"url": "https://github.com/obergodmar"
},
"engines": {
"node": "10.18.1"
},
"dependencies": {
"classnames": "^2.2.6",
"react": "^16.13.1",
@@ -15,18 +19,50 @@
"serve": "^11.3.2"
},
"devDependencies": {
"@jest/globals": "^26.3.0",
"@types/classnames": "^2.2.10",
"@types/react": "^16.9.41",
"@types/react-dom": "^16.9.8",
"@typescript-eslint/eslint-plugin": "^3.9.1",
"@typescript-eslint/parser": "^3.9.1",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.3",
"enzyme-to-json": "^3.5.0",
"eslint-config-airbnb": "^18.2.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-import": "^2.22.0",
"eslint-plugin-jest": "^23.20.0",
"eslint-plugin-jsx-a11y": "^6.3.1",
"eslint-plugin-prettier": "^3.1.4",
"eslint-plugin-react": "^7.20.5",
"eslint-plugin-react-hooks": "^4.0.8",
"husky": "^4.2.5",
"jest-css-modules": "^2.1.0",
"node-sass": "^4.14.1",
"tslint": "^6.1.2",
"prettier": "^2.0.5",
"stylelint": "^13.6.1",
"stylelint-config-rational-order": "^0.1.2",
"stylelint-config-recommended-scss": "^4.2.0",
"stylelint-config-standard": "^20.0.0",
"stylelint-scss": "^3.18.0",
"typescript": "^3.9.5"
},
"scripts": {
"start": "serve ./build",
"dev": "react-scripts start",
"build": "env GENERATE_SOURCEMAP=false react-scripts build",
"eject": "react-scripts eject"
"eslint": "npx eslint --ext .ts,.tsx ./src",
"eslint:fix": "npx eslint --ext .ts,.tsx . --fix ./src",
"stylelint": "npx stylelint \"src/**/*.scss\"",
"stylelint:fix": "npx stylelint --fix \"src/**/*.scss\"",
"test": "npm run test:u && npm run test:cov",
"test:u": "jest -u",
"test:cov": "jest --coverage"
},
"husky": {
"hooks": {
"pre-commit": "yarn eslint && yarn stylelint"
}
},
"eslintConfig": {
"extends": "react-app"
+138 -86
View File
@@ -1,5 +1,13 @@
import * as React from 'react'
import { KeyboardEvent, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState } from 'react'
import * as React from "react";
import {
KeyboardEvent,
useCallback,
useEffect,
useLayoutEffect,
useMemo,
useRef,
useState,
} from "react";
import {
MainMenuComponent,
@@ -8,133 +16,178 @@ import {
PanelComponent,
PreviewComponent,
SettingsComponent,
ViewComponent
} from '../components'
import places from '../assets'
import { delay, soundLoad, UI_SOUND_VOLUME } from '../utils'
import { useSettings } from '../hooks'
ViewComponent,
} from "../components";
import places from "../assets";
import { delay, soundLoad, UI_SOUND_VOLUME } from "../utils";
import { useSettings } from "../hooks";
import PanelOpenAudio from '../assets/audio/panel-open.ogg'
import PanelCloseAudio from '../assets/audio/panel-close.ogg'
import PanelOpenAudio from "../assets/audio/panel-open.ogg";
import PanelCloseAudio from "../assets/audio/panel-close.ogg";
import SettingsOpenAudio from '../assets/audio/menu-open.ogg'
import SettingsCloseAudio from '../assets/audio/menu-close.ogg'
import SettingsOpenAudio from "../assets/audio/menu-open.ogg";
import SettingsCloseAudio from "../assets/audio/menu-close.ogg";
import CheckBoxOnAudio from '../assets/audio/check-box-on.ogg'
import CheckBoxOffAudio from '../assets/audio/check-box-off.ogg'
import CheckBoxOnAudio from "../assets/audio/check-box-on.ogg";
import CheckBoxOffAudio from "../assets/audio/check-box-off.ogg";
import Sound from '../modules/sound'
import Sound from "../modules/sound";
import './style.scss'
import "./style.scss";
export default function App() {
const {settings: {uiSound, musicVolume, language}} = useSettings()
const [isSettingsShown, setSettingsShown] = useState(false)
const [isLoading, setLoading] = useState(false)
const [isPlaying, setPlaying] = useState(false)
const [isLeftPanelShown, setLeftPanelShown] = useState(false)
const [isBottomPanelShown, setBottomPanelShown] = useState(false)
const [activePlace, setActivePlace] = useState(0)
const [activeView, setActiveView] = useState(0)
export default function App(): JSX.Element {
const {
settings: { uiSound, musicVolume, language },
} = useSettings();
const [isSettingsShown, setSettingsShown] = useState(false);
const [isLoading, setLoading] = useState(false);
const [isPlaying, setPlaying] = useState(false);
const [isLeftPanelShown, setLeftPanelShown] = useState(false);
const [isBottomPanelShown, setBottomPanelShown] = useState(false);
const [activePlace, setActivePlace] = useState(0);
const [activeView, setActiveView] = useState(0);
const panelOpenSound = useMemo(() => soundLoad(PanelOpenAudio, UI_SOUND_VOLUME), [])
const panelCloseSound = useMemo(() => soundLoad(PanelCloseAudio, UI_SOUND_VOLUME), [])
const settingsOpenSound = useMemo(() => soundLoad(SettingsOpenAudio, UI_SOUND_VOLUME), [])
const settingsCloseSound = useMemo(() => soundLoad(SettingsCloseAudio, UI_SOUND_VOLUME), [])
const checkboxOnSound = useMemo(() => soundLoad(CheckBoxOnAudio, UI_SOUND_VOLUME), [])
const checkboxOffSound = useMemo(() => soundLoad(CheckBoxOffAudio, UI_SOUND_VOLUME), [])
const panelOpenSound = useMemo(
() => soundLoad(PanelOpenAudio, UI_SOUND_VOLUME),
[]
);
const panelCloseSound = useMemo(
() => soundLoad(PanelCloseAudio, UI_SOUND_VOLUME),
[]
);
const settingsOpenSound = useMemo(
() => soundLoad(SettingsOpenAudio, UI_SOUND_VOLUME),
[]
);
const settingsCloseSound = useMemo(
() => soundLoad(SettingsCloseAudio, UI_SOUND_VOLUME),
[]
);
const checkboxOnSound = useMemo(
() => soundLoad(CheckBoxOnAudio, UI_SOUND_VOLUME),
[]
);
const checkboxOffSound = useMemo(
() => soundLoad(CheckBoxOffAudio, UI_SOUND_VOLUME),
[]
);
const [currentPlaying, setCurrentPlaying] = useState<Sound>()
const [currentPlaying, setCurrentPlaying] = useState<Sound>();
const app = useRef<HTMLDivElement>(null)
const app = useRef<HTMLDivElement>(null);
const handleHideLeftPanel = useCallback(() => {
setBottomPanelShown(false)
setLeftPanelShown(!isLeftPanelShown)
}, [isLeftPanelShown])
setBottomPanelShown(false);
setLeftPanelShown(!isLeftPanelShown);
}, [isLeftPanelShown]);
const handleHideBottomPanel = useCallback(() => {
setLeftPanelShown(false)
setBottomPanelShown(!isBottomPanelShown)
}, [isBottomPanelShown])
setLeftPanelShown(false);
setBottomPanelShown(!isBottomPanelShown);
}, [isBottomPanelShown]);
const delayedChange = useCallback((fn: (value: number) => void, value: number) => {
const delayedChange = useCallback(
(fn: (value: number) => void, value: number) => {
if (isLoading) {
return
return;
}
fn(value)
setLoading(true)
fn(value);
setLoading(true);
delay().then(() => {
setLoading(false)
})
}, [isLoading])
setLoading(false);
});
},
[isLoading]
);
const handleLeftPreviewClick = useCallback((value: number) => {
delayedChange(setActivePlace, value)
setActiveView(0)
}, [delayedChange])
const handleLeftPreviewClick = useCallback(
(value: number) => {
delayedChange(setActivePlace, value);
setActiveView(0);
},
[delayedChange]
);
const handleBottomPreviewClick = useCallback((value: number) => {
delayedChange(setActiveView, value)
}, [delayedChange])
const handleBottomPreviewClick = useCallback(
(value: number) => {
delayedChange(setActiveView, value);
},
[delayedChange]
);
useEffect(() => {
if (app && app.current) {
app.current.focus()
app.current.focus();
}
}, [app])
}, [app]);
useLayoutEffect(() => {
document.title = language[`place.${places[activePlace].name}` as keyof typeof language]
}, [activePlace, language])
document.title =
language[`place.${places[activePlace].name}` as keyof typeof language];
}, [activePlace, language]);
useEffect(() => {
if (!currentPlaying) {
return
return;
}
currentPlaying.setVolume(musicVolume)
currentPlaying.playMusic()
}, [currentPlaying, musicVolume])
currentPlaying.setVolume(musicVolume);
currentPlaying.playMusic();
}, [currentPlaying, musicVolume]);
const appClick = useCallback(() => currentPlaying && currentPlaying.playMusic(), [currentPlaying])
const appClick = useCallback(
() => currentPlaying && currentPlaying.playMusic(),
[currentPlaying]
);
const openCloseSettings = useCallback(() => {
setSettingsShown(!isSettingsShown)
setSettingsShown(!isSettingsShown);
if (app && app.current) {
app.current.focus()
app.current.focus();
}
if (!uiSound) {
return
return;
}
if (isSettingsShown) {
settingsCloseSound.playSound()
settingsCloseSound.playSound();
} else {
settingsOpenSound.playSound()
settingsOpenSound.playSound();
}
}, [app, isSettingsShown, uiSound, settingsCloseSound, settingsOpenSound])
}, [app, isSettingsShown, uiSound, settingsCloseSound, settingsOpenSound]);
const handleOpenSettings = useCallback((e: KeyboardEvent) => {
const handleOpenSettings = useCallback(
(e: KeyboardEvent) => {
switch (e.keyCode) {
case 27:
if (isLeftPanelShown || isBottomPanelShown) {
setLeftPanelShown(false)
setBottomPanelShown(false)
break
setLeftPanelShown(false);
setBottomPanelShown(false);
break;
}
openCloseSettings()
break
openCloseSettings();
break;
case 32:
if (!currentPlaying) {
return
return;
}
if (isPlaying) {
currentPlaying.pause()
setPlaying(false)
currentPlaying.pause();
setPlaying(false);
} else {
currentPlaying.playMusic()
currentPlaying.playMusic();
}
break;
default:
break;
}
}, [isLeftPanelShown, isBottomPanelShown, isPlaying, currentPlaying, openCloseSettings])
},
[
isLeftPanelShown,
isBottomPanelShown,
isPlaying,
currentPlaying,
openCloseSettings,
]
);
return (
<div
@@ -142,11 +195,11 @@ export default function App() {
onClick={appClick}
onKeyDown={handleOpenSettings}
tabIndex={0}
className='main'
className="main"
>
<ViewComponent src={places[activePlace].view[activeView]} />
<MainMenuComponent>
<div className='author'>
<div className="author">
<a href="https://github.com/obergodmar">obergodmar</a>
<span>v1.3.1</span>
</div>
@@ -159,7 +212,7 @@ export default function App() {
openSoundPlay={panelOpenSound.playSound}
closeSoundPlay={panelCloseSound.playSound}
itemsCount={places.length || 0}
orientation='left'
orientation="left"
isShown={isLeftPanelShown}
setShown={handleHideLeftPanel}
>
@@ -178,7 +231,7 @@ export default function App() {
openSoundPlay={panelOpenSound.playSound}
closeSoundPlay={panelCloseSound.playSound}
itemsCount={places[activePlace].preview.length || 0}
orientation='bottom'
orientation="bottom"
isShown={isBottomPanelShown}
setShown={handleHideBottomPanel}
>
@@ -198,15 +251,14 @@ export default function App() {
checkboxOnSoundPlay={checkboxOnSound.playSound}
checkboxOffSoundPlay={checkboxOffSound.playSound}
/>
)
}
)}
<MusicComponent
music={places[activePlace].music}
setPlaying={setPlaying}
setCurrentPlaying={setCurrentPlaying}
/>
</div>
)
);
}
App.displayName = 'App'
App.displayName = "App";
+24 -24
View File
@@ -1,10 +1,10 @@
@import "../assets/assets";
$hoverColor: rgba(173, 154, 32, 0.75);
$hoverColor: rgba(173, 154, 32, .75);
$hoverBox: 0 0 4px 2px $hoverColor;
$previewHeight: 180px;
$previewWidth: 320px;
$font: 'Arial Narrow';
$font: "Arial Narrow";
$fontSpacing: 1.2px;
$fontSize: 14px;
//$fontShadow: 2px 2px 2px #000;
@@ -20,39 +20,39 @@ $fontColor: #eec511;
$fontColorWhite: #fff;
$transitionDuration: 500ms;
$transitionType: cubic-bezier(1, .35, .57, 1);
$settingsBackground: rgba(0, 0, 0, 0.6);
$settingsBackground: rgba(0, 0, 0, .6);
body {
cursor: $cursor, auto;
overflow: hidden;
background-image: $backgroundTexture;
background-repeat: repeat;
overflow: hidden;
cursor: $cursor, auto;
}
.main {
position: relative;
width: 100vw;
height: 100vh;
overflow: hidden;
position: relative;
}
.author {
padding: 0 10px;
width: 0;
opacity: 0;
font-family: $font;
text-shadow: $fontShadow;
color: $fontColor;
font-size: 16px;
display: flex;
align-items: center;
transition: width $transitionDuration $transitionType, opacity $transitionDuration $transitionType;
justify-content: space-between;
width: 0;
padding: 0 10px;
color: $fontColor;
font-size: 16px;
font-family: $font;
text-shadow: $fontShadow;
opacity: 0;
transition: width $transitionDuration $transitionType, opacity $transitionDuration $transitionType;
a {
cursor: $cursorPointer, auto;
color: inherit;
text-decoration: none;
cursor: $cursorPointer, auto;
&:focus {
outline: none;
@@ -64,21 +64,21 @@ body {
button {
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
font-family: $font;
font-size: $fontSize;
text-shadow: $fontShadow;
letter-spacing: $fontSpacing;
color: $fontColor;
cursor: $cursor, auto;
justify-content: flex-start;
width: $buttonWidth;
height: $buttonHeight;
border: none;
border-radius: 6px;
color: $fontColor;
font-size: $fontSize;
font-family: $font;
letter-spacing: $fontSpacing;
text-shadow: $fontShadow;
background-color: unset;
background-image: $buttonUp;
background-position: -2px -2px;
border: none;
border-radius: 6px;
cursor: $cursor, auto;
&:hover {
background-image: $buttonHover, $buttonUp;
+25 -25
View File
File diff suppressed because one or more lines are too long
+6 -6
View File
@@ -1,10 +1,10 @@
import preview from './preview'
import view from './view'
import music from './music'
import preview from "./preview";
import view from "./view";
import music from "./music";
export default {
name: 'crystalsong-forest',
name: "crystalsong-forest",
music,
view,
preview
}
preview,
};
+6 -6
View File
@@ -1,11 +1,11 @@
import CrystalsongForest1 from './crystalsong-forest-music-1.ogg'
import CrystalsongForest2 from './crystalsong-forest-music-2.ogg'
import CrystalsongForest3 from './crystalsong-forest-music-3.ogg'
import CrystalsongForest4 from './crystalsong-forest-music-4.ogg'
import CrystalsongForest1 from "./crystalsong-forest-music-1.ogg";
import CrystalsongForest2 from "./crystalsong-forest-music-2.ogg";
import CrystalsongForest3 from "./crystalsong-forest-music-3.ogg";
import CrystalsongForest4 from "./crystalsong-forest-music-4.ogg";
export default [
CrystalsongForest1,
CrystalsongForest2,
CrystalsongForest3,
CrystalsongForest4
]
CrystalsongForest4,
];
@@ -1,13 +1,13 @@
import CrystalsongForest1 from './crystalsong-forest-1.jpg'
import CrystalsongForest2 from './crystalsong-forest-2.jpg'
import CrystalsongForest3 from './crystalsong-forest-3.jpg'
import CrystalsongForest4 from './crystalsong-forest-4.jpg'
import CrystalsongForest5 from './crystalsong-forest-5.jpg'
import CrystalsongForest1 from "./crystalsong-forest-1.jpg";
import CrystalsongForest2 from "./crystalsong-forest-2.jpg";
import CrystalsongForest3 from "./crystalsong-forest-3.jpg";
import CrystalsongForest4 from "./crystalsong-forest-4.jpg";
import CrystalsongForest5 from "./crystalsong-forest-5.jpg";
export default [
CrystalsongForest1,
CrystalsongForest2,
CrystalsongForest3,
CrystalsongForest4,
CrystalsongForest5
]
CrystalsongForest5,
];
+7 -7
View File
@@ -1,13 +1,13 @@
import CrystalsongForest1 from './crystalsong-forest-1.jpg'
import CrystalsongForest2 from './crystalsong-forest-2.jpg'
import CrystalsongForest3 from './crystalsong-forest-3.jpg'
import CrystalsongForest4 from './crystalsong-forest-4.jpg'
import CrystalsongForest5 from './crystalsong-forest-5.jpg'
import CrystalsongForest1 from "./crystalsong-forest-1.jpg";
import CrystalsongForest2 from "./crystalsong-forest-2.jpg";
import CrystalsongForest3 from "./crystalsong-forest-3.jpg";
import CrystalsongForest4 from "./crystalsong-forest-4.jpg";
import CrystalsongForest5 from "./crystalsong-forest-5.jpg";
export default [
CrystalsongForest1,
CrystalsongForest2,
CrystalsongForest3,
CrystalsongForest4,
CrystalsongForest5
]
CrystalsongForest5,
];
+6 -6
View File
@@ -1,10 +1,10 @@
import preview from './preview'
import view from './view'
import music from './music'
import preview from "./preview";
import view from "./view";
import music from "./music";
export default {
name: 'dalaran',
name: "dalaran",
music,
view,
preview
}
preview,
};
+7 -7
View File
@@ -1,13 +1,13 @@
import DalaranMusic1 from './dalaran-music-1.ogg'
import DalaranMusic2 from './dalaran-music-2.ogg'
import DalaranMusic3 from './dalaran-music-3.ogg'
import DalaranMusic4 from './dalaran-music-4.ogg'
import DalaranMusic5 from './dalaran-music-5.ogg'
import DalaranMusic1 from "./dalaran-music-1.ogg";
import DalaranMusic2 from "./dalaran-music-2.ogg";
import DalaranMusic3 from "./dalaran-music-3.ogg";
import DalaranMusic4 from "./dalaran-music-4.ogg";
import DalaranMusic5 from "./dalaran-music-5.ogg";
export default [
DalaranMusic1,
DalaranMusic2,
DalaranMusic3,
DalaranMusic4,
DalaranMusic5
]
DalaranMusic5,
];
+6 -12
View File
@@ -1,13 +1,7 @@
import Dalaran1 from './dalaran-1.jpg'
import Dalaran2 from './dalaran-2.jpg'
import Dalaran3 from './dalaran-3.jpg'
import Dalaran4 from './dalaran-4.jpg'
import Dalaran5 from './dalaran-5.jpg'
import Dalaran1 from "./dalaran-1.jpg";
import Dalaran2 from "./dalaran-2.jpg";
import Dalaran3 from "./dalaran-3.jpg";
import Dalaran4 from "./dalaran-4.jpg";
import Dalaran5 from "./dalaran-5.jpg";
export default [
Dalaran1,
Dalaran2,
Dalaran3,
Dalaran4,
Dalaran5
]
export default [Dalaran1, Dalaran2, Dalaran3, Dalaran4, Dalaran5];
+6 -12
View File
@@ -1,13 +1,7 @@
import Dalaran1 from './dalaran-1.jpg'
import Dalaran2 from './dalaran-2.jpg'
import Dalaran3 from './dalaran-3.jpg'
import Dalaran4 from './dalaran-4.jpg'
import Dalaran5 from './dalaran-5.jpg'
import Dalaran1 from "./dalaran-1.jpg";
import Dalaran2 from "./dalaran-2.jpg";
import Dalaran3 from "./dalaran-3.jpg";
import Dalaran4 from "./dalaran-4.jpg";
import Dalaran5 from "./dalaran-5.jpg";
export default [
Dalaran1,
Dalaran2,
Dalaran3,
Dalaran4,
Dalaran5
]
export default [Dalaran1, Dalaran2, Dalaran3, Dalaran4, Dalaran5];
+6 -6
View File
@@ -1,10 +1,10 @@
import preview from './preview'
import view from './view'
import music from './music'
import preview from "./preview";
import view from "./view";
import music from "./music";
export default {
name: 'halls-of-valor',
name: "halls-of-valor",
music,
view,
preview
}
preview,
};
+2 -4
View File
@@ -1,5 +1,3 @@
import HallsOfValorMusic1 from './halls-of-valor-music-1.mp3'
import HallsOfValorMusic1 from "./halls-of-valor-music-1.mp3";
export default [
HallsOfValorMusic1
]
export default [HallsOfValorMusic1];
+5 -10
View File
@@ -1,11 +1,6 @@
import HallsOfValor1 from './halls-of-valor-1.jpg'
import HallsOfValor2 from './halls-of-valor-2.jpg'
import HallsOfValor3 from './halls-of-valor-3.jpg'
import HallsOfValor4 from './halls-of-valor-4.jpg'
import HallsOfValor1 from "./halls-of-valor-1.jpg";
import HallsOfValor2 from "./halls-of-valor-2.jpg";
import HallsOfValor3 from "./halls-of-valor-3.jpg";
import HallsOfValor4 from "./halls-of-valor-4.jpg";
export default [
HallsOfValor1,
HallsOfValor2,
HallsOfValor3,
HallsOfValor4
]
export default [HallsOfValor1, HallsOfValor2, HallsOfValor3, HallsOfValor4];
+5 -10
View File
@@ -1,11 +1,6 @@
import HallsOfValor1 from './halls-of-valor-1.jpg'
import HallsOfValor2 from './halls-of-valor-2.jpg'
import HallsOfValor3 from './halls-of-valor-3.jpg'
import HallsOfValor4 from './halls-of-valor-4.jpg'
import HallsOfValor1 from "./halls-of-valor-1.jpg";
import HallsOfValor2 from "./halls-of-valor-2.jpg";
import HallsOfValor3 from "./halls-of-valor-3.jpg";
import HallsOfValor4 from "./halls-of-valor-4.jpg";
export default [
HallsOfValor1,
HallsOfValor2,
HallsOfValor3,
HallsOfValor4
]
export default [HallsOfValor1, HallsOfValor2, HallsOfValor3, HallsOfValor4];
+12 -10
View File
File diff suppressed because one or more lines are too long
+6 -6
View File
@@ -1,10 +1,10 @@
import preview from './preview'
import view from './view'
import music from './music'
import preview from "./preview";
import view from "./view";
import music from "./music";
export default {
name: 'nagrand',
name: "nagrand",
music,
view,
preview
}
preview,
};
+5 -10
View File
@@ -1,11 +1,6 @@
import NagrandMusic1 from './nagrand-music-1.ogg'
import NagrandMusic2 from './nagrand-music-2.ogg'
import NagrandMusic3 from './nagrand-music-3.ogg'
import NagrandMusic4 from './nagrand-music-4.ogg'
import NagrandMusic1 from "./nagrand-music-1.ogg";
import NagrandMusic2 from "./nagrand-music-2.ogg";
import NagrandMusic3 from "./nagrand-music-3.ogg";
import NagrandMusic4 from "./nagrand-music-4.ogg";
export default [
NagrandMusic1,
NagrandMusic2,
NagrandMusic3,
NagrandMusic4
]
export default [NagrandMusic1, NagrandMusic2, NagrandMusic3, NagrandMusic4];
+6 -12
View File
@@ -1,13 +1,7 @@
import Nagrand1 from './nagrand-1.jpg'
import Nagrand2 from './nagrand-2.jpg'
import Nagrand3 from './nagrand-3.jpg'
import Nagrand4 from './nagrand-4.jpg'
import Nagrand5 from './nagrand-5.jpg'
import Nagrand1 from "./nagrand-1.jpg";
import Nagrand2 from "./nagrand-2.jpg";
import Nagrand3 from "./nagrand-3.jpg";
import Nagrand4 from "./nagrand-4.jpg";
import Nagrand5 from "./nagrand-5.jpg";
export default [
Nagrand1,
Nagrand2,
Nagrand3,
Nagrand4,
Nagrand5
]
export default [Nagrand1, Nagrand2, Nagrand3, Nagrand4, Nagrand5];
+6 -12
View File
@@ -1,13 +1,7 @@
import Nagrand1 from './nagrand-1.jpg'
import Nagrand2 from './nagrand-2.jpg'
import Nagrand3 from './nagrand-3.jpg'
import Nagrand4 from './nagrand-4.jpg'
import Nagrand5 from './nagrand-5.jpg'
import Nagrand1 from "./nagrand-1.jpg";
import Nagrand2 from "./nagrand-2.jpg";
import Nagrand3 from "./nagrand-3.jpg";
import Nagrand4 from "./nagrand-4.jpg";
import Nagrand5 from "./nagrand-5.jpg";
export default [
Nagrand1,
Nagrand2,
Nagrand3,
Nagrand4,
Nagrand5
]
export default [Nagrand1, Nagrand2, Nagrand3, Nagrand4, Nagrand5];
+6 -6
View File
@@ -1,10 +1,10 @@
import preview from './preview'
import view from './view'
import music from './music'
import preview from "./preview";
import view from "./view";
import music from "./music";
export default {
name: 'pandaria',
name: "pandaria",
music,
view,
preview
}
preview,
};
+5 -10
View File
@@ -1,11 +1,6 @@
import Pandaria1 from './pandaria-music-1.mp3'
import Pandaria2 from './pandaria-music-2.mp3'
import Pandaria3 from './pandaria-music-3.mp3'
import Pandaria4 from './pandaria-music-4.mp3'
import Pandaria1 from "./pandaria-music-1.mp3";
import Pandaria2 from "./pandaria-music-2.mp3";
import Pandaria3 from "./pandaria-music-3.mp3";
import Pandaria4 from "./pandaria-music-4.mp3";
export default [
Pandaria1,
Pandaria2,
Pandaria3,
Pandaria4
]
export default [Pandaria1, Pandaria2, Pandaria3, Pandaria4];
+8 -8
View File
@@ -1,9 +1,9 @@
import Pandaria1 from './pandaria-1.jpg'
import Pandaria2 from './pandaria-2.jpg'
import Pandaria3 from './pandaria-3.jpg'
import Pandaria4 from './pandaria-4.jpg'
import Pandaria5 from './pandaria-5.jpg'
import Pandaria6 from './pandaria-6.jpg'
import Pandaria1 from "./pandaria-1.jpg";
import Pandaria2 from "./pandaria-2.jpg";
import Pandaria3 from "./pandaria-3.jpg";
import Pandaria4 from "./pandaria-4.jpg";
import Pandaria5 from "./pandaria-5.jpg";
import Pandaria6 from "./pandaria-6.jpg";
export default [
Pandaria1,
@@ -11,5 +11,5 @@ export default [
Pandaria3,
Pandaria4,
Pandaria5,
Pandaria6
]
Pandaria6,
];
+8 -8
View File
@@ -1,9 +1,9 @@
import Pandaria1 from './pandaria-1.jpg'
import Pandaria2 from './pandaria-2.jpg'
import Pandaria3 from './pandaria-3.jpg'
import Pandaria4 from './pandaria-4.jpg'
import Pandaria5 from './pandaria-5.jpg'
import Pandaria6 from './pandaria-6.jpg'
import Pandaria1 from "./pandaria-1.jpg";
import Pandaria2 from "./pandaria-2.jpg";
import Pandaria3 from "./pandaria-3.jpg";
import Pandaria4 from "./pandaria-4.jpg";
import Pandaria5 from "./pandaria-5.jpg";
import Pandaria6 from "./pandaria-6.jpg";
export default [
Pandaria1,
@@ -11,5 +11,5 @@ export default [
Pandaria3,
Pandaria4,
Pandaria5,
Pandaria6
]
Pandaria6,
];
+6 -6
View File
@@ -1,10 +1,10 @@
import preview from './preview'
import view from './view'
import music from './music'
import preview from "./preview";
import view from "./view";
import music from "./music";
export default {
name: 'stormwind-park',
name: "stormwind-park",
music,
view,
preview
}
preview,
};
+3 -6
View File
@@ -1,7 +1,4 @@
import StormwindMusic1 from './stormwind-park-music-1.mp3'
import StormwindMusic2 from './stormwind-park-music-2.mp3'
import StormwindMusic1 from "./stormwind-park-music-1.mp3";
import StormwindMusic2 from "./stormwind-park-music-2.mp3";
export default [
StormwindMusic1,
StormwindMusic2
]
export default [StormwindMusic1, StormwindMusic2];
+11 -11
View File
@@ -1,12 +1,12 @@
import StormwindPark1 from './stormwind-park-1.jpg'
import StormwindPark2 from './stormwind-park-2.jpg'
import StormwindPark3 from './stormwind-park-3.jpg'
import StormwindPark4 from './stormwind-park-4.jpg'
import StormwindPark5 from './stormwind-park-5.jpg'
import StormwindPark6 from './stormwind-park-6.jpg'
import StormwindPark7 from './stormwind-park-7.jpg'
import StormwindPark8 from './stormwind-park-8.jpg'
import StormwindPark9 from './stormwind-park-9.jpg'
import StormwindPark1 from "./stormwind-park-1.jpg";
import StormwindPark2 from "./stormwind-park-2.jpg";
import StormwindPark3 from "./stormwind-park-3.jpg";
import StormwindPark4 from "./stormwind-park-4.jpg";
import StormwindPark5 from "./stormwind-park-5.jpg";
import StormwindPark6 from "./stormwind-park-6.jpg";
import StormwindPark7 from "./stormwind-park-7.jpg";
import StormwindPark8 from "./stormwind-park-8.jpg";
import StormwindPark9 from "./stormwind-park-9.jpg";
export default [
StormwindPark1,
@@ -17,5 +17,5 @@ export default [
StormwindPark6,
StormwindPark7,
StormwindPark8,
StormwindPark9
]
StormwindPark9,
];
+11 -11
View File
@@ -1,12 +1,12 @@
import StormwindPark1 from './stormwind-park-1.jpg'
import StormwindPark2 from './stormwind-park-2.jpg'
import StormwindPark3 from './stormwind-park-3.jpg'
import StormwindPark4 from './stormwind-park-4.jpg'
import StormwindPark5 from './stormwind-park-5.jpg'
import StormwindPark6 from './stormwind-park-6.jpg'
import StormwindPark7 from './stormwind-park-7.jpg'
import StormwindPark8 from './stormwind-park-8.jpg'
import StormwindPark9 from './stormwind-park-9.jpg'
import StormwindPark1 from "./stormwind-park-1.jpg";
import StormwindPark2 from "./stormwind-park-2.jpg";
import StormwindPark3 from "./stormwind-park-3.jpg";
import StormwindPark4 from "./stormwind-park-4.jpg";
import StormwindPark5 from "./stormwind-park-5.jpg";
import StormwindPark6 from "./stormwind-park-6.jpg";
import StormwindPark7 from "./stormwind-park-7.jpg";
import StormwindPark8 from "./stormwind-park-8.jpg";
import StormwindPark9 from "./stormwind-park-9.jpg";
export default [
StormwindPark1,
@@ -17,5 +17,5 @@ export default [
StormwindPark6,
StormwindPark7,
StormwindPark8,
StormwindPark9
]
StormwindPark9,
];
@@ -4,22 +4,22 @@ $borderWidth: 12px;
$borderOutset: 8px;
.header {
font-family: $font;
font-size: $fontSize;
text-shadow: $fontShadow;
letter-spacing: $fontSpacing;
color: $fontColor;
height: 100%;
width: 100%;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
padding-bottom: 2px;
color: $fontColor;
font-size: $fontSize;
font-family: $font;
letter-spacing: $fontSpacing;
text-shadow: $fontShadow;
background-image: $backgroundTexture;
background-repeat: repeat;
border: $borderWidth double $fontColor;
border-image: $border 15 15 15 15 fill;
border-image-outset: $borderOutset;
border-image-repeat: stretch stretch;
background-image: $backgroundTexture;
background-repeat: repeat;
}
@@ -1,15 +1,13 @@
import * as React from 'react'
import * as React from "react";
import './bordered-header.scss'
import "./bordered-header.scss";
interface Props {
children: React.ReactNode
children: React.ReactNode;
}
export const BorderedHeader = ({children}: Props) => (
<div className='header'>
{children}
</div>
)
export const BorderedHeader: React.FC<Props> = ({ children }: Props) => (
<div className="header">{children}</div>
);
BorderedHeader.displayName = 'BorderedHeader'
BorderedHeader.displayName = "BorderedHeader";
@@ -3,8 +3,8 @@
.checkbox {
width: 32px;
height: 32px;
border-radius: 8px;
background-image: $checkbox;
border-radius: 8px;
&:focus {
outline: none;
@@ -1,32 +1,40 @@
import * as React from 'react'
import { KeyboardEvent, useCallback } from 'react'
import cn from 'classnames'
import * as React from "react";
import { KeyboardEvent, useCallback } from "react";
import cn from "classnames";
import './checkbox-component.scss'
import { Settings } from "../../settings-context";
import "./checkbox-component.scss";
interface Props {
handleClick: (option: any) => void
optionName: any
value: boolean
handleClick: (option: keyof Settings) => void;
optionName: keyof Settings;
value: boolean;
}
export const CheckBoxComponent = ({handleClick, optionName, value}: Props) => {
const handleKeyDown = useCallback((e: KeyboardEvent, option: any) => {
export const CheckBoxComponent: React.FC<Props> = ({
handleClick,
optionName,
value,
}: Props) => {
const handleKeyDown = useCallback(
(e: KeyboardEvent, option: keyof Settings) => {
if (e.keyCode !== 13 && e.keyCode !== 32) {
return
return;
}
handleClick(option)
}, [handleClick])
handleClick(option);
},
[handleClick]
);
return (
<div
tabIndex={0}
onClick={() => handleClick(optionName)}
onKeyDown={(e) => handleKeyDown(e, optionName)}
className={cn('checkbox', {'checkbox--checked': value})}
className={cn("checkbox", { "checkbox--checked": value })}
/>
)
}
);
};
CheckBoxComponent.displayName = 'CheckBoxComponent'
CheckBoxComponent.displayName = "CheckBoxComponent";
+11 -11
View File
@@ -1,11 +1,11 @@
export { ViewComponent } from './view-component/view-component'
export { SelectComponent } from './select-component/select-component'
export { PanelComponent } from './panel-component/panel-component'
export { PreviewComponent } from './preview-component/preview-component'
export { RangeComponent } from './range-component/range-component'
export { SettingsComponent } from './settings-component/settings-component'
export { CheckBoxComponent } from './checkbox-component/checkbox-component'
export { BorderedHeader } from './bordered-header/bordered-header'
export { MusicComponent } from './music-component/music-component'
export { MainMenuComponent } from './main-menu-component/main-menu-component'
export { MenuItemComponent } from './menu-item-component/menu-item-component'
export { ViewComponent } from "./view-component/view-component";
export { SelectComponent } from "./select-component/select-component";
export { PanelComponent } from "./panel-component/panel-component";
export { PreviewComponent } from "./preview-component/preview-component";
export { RangeComponent } from "./range-component/range-component";
export { SettingsComponent } from "./settings-component/settings-component";
export { CheckBoxComponent } from "./checkbox-component/checkbox-component";
export { BorderedHeader } from "./bordered-header/bordered-header";
export { MusicComponent } from "./music-component/music-component";
export { MainMenuComponent } from "./main-menu-component/main-menu-component";
export { MenuItemComponent } from "./menu-item-component/menu-item-component";
@@ -5,19 +5,19 @@ $menuWidth: 290px;
.main-menu {
position: absolute;
right: 0;
top: 0;
right: 0;
z-index: 3;
display: flex;
align-items: center;
justify-content: flex-end;
border: 1px double $fontColor;
border-image: $rangeBorder 5 5 5 5;
padding: 2px 3px;
background: $panelBackground center repeat;
border: 1px double $fontColor;
border-radius: 6px;
border-image: $rangeBorder 5 5 5 5;
border-image-width: 5px;
border-image-repeat: round round;
border-radius: 6px;
padding: 2px 3px;
&:hover {
.author {
@@ -1,17 +1,13 @@
import * as React from 'react'
import * as React from "react";
import './main-menu-component.scss'
import "./main-menu-component.scss";
interface Props {
children: React.ReactNode
children: React.ReactNode;
}
export const MainMenuComponent = ({children}: Props) => {
return (
<div className='main-menu'>
{children}
</div>
)
}
export const MainMenuComponent: React.FC<Props> = ({ children }: Props) => {
return <div className="main-menu">{children}</div>;
};
MainMenuComponent.displayName = 'MainMenuComponent'
MainMenuComponent.displayName = "MainMenuComponent";
@@ -1,4 +1,4 @@
@import '../../app/style';
@import "../../app/style";
$menuItemWidth: 32px;
$menuItemHeight: 41px;
@@ -7,11 +7,11 @@ $menuItemHeight: 41px;
z-index: 4;
width: $menuItemWidth - 4px;
height: $menuItemHeight - 4px;
border-radius: 6px;
background-image: $helpButton;
background-position: center;
background-repeat: no-repeat;
background-position: center;
background-size: $menuItemWidth $menuItemHeight;
border-radius: 6px;
&--active {
background-image: $helpButtonClick;
@@ -1,31 +1,36 @@
import * as React from 'react'
import { KeyboardEvent, useCallback } from 'react'
import cn from 'classnames'
import * as React from "react";
import { KeyboardEvent, useCallback } from "react";
import cn from "classnames";
import './menu-item-component.scss'
import "./menu-item-component.scss";
interface Props {
isActive: boolean
handleClick: () => void
isActive: boolean;
handleClick: () => void;
}
export const MenuItemComponent = ({isActive, handleClick}: Props) => {
const handleKeyDown = useCallback((e: KeyboardEvent) => {
export const MenuItemComponent: React.FC<Props> = ({
isActive,
handleClick,
}: Props) => {
const handleKeyDown = useCallback(
(e: KeyboardEvent) => {
if (e.keyCode !== 13 && e.keyCode !== 32) {
return
return;
}
handleClick()
}, [handleClick])
handleClick();
},
[handleClick]
);
return (
<div
tabIndex={0}
onClick={handleClick}
onKeyDown={handleKeyDown}
className={cn('menu-item', {'menu-item--active': isActive})}
className={cn("menu-item", { "menu-item--active": isActive })}
/>
)
}
);
};
MenuItemComponent.displayName = 'MainMenuComponent'
MenuItemComponent.displayName = "MainMenuComponent";
@@ -1,42 +1,49 @@
import { useEffect, useMemo } from 'react'
import { randomNumber, soundLoad, UI_MUSIC_VOLUME } from '../../utils'
import Sound from '../../modules/sound'
import * as React from "react";
import { useEffect, useMemo } from "react";
import { randomNumber, soundLoad, UI_MUSIC_VOLUME } from "../../utils";
import Sound from "../../modules/sound";
interface Props {
music: string[]
setPlaying: (value: boolean) => void
setCurrentPlaying: (value: Sound | undefined) => void
music: string[];
setPlaying: (value: boolean) => void;
setCurrentPlaying: (value: Sound | undefined) => void;
}
export const MusicComponent = ({ music, setPlaying, setCurrentPlaying }: Props) => {
const musicArray = useMemo(() => (
music.map(sound => soundLoad(sound, UI_MUSIC_VOLUME))
), [music])
/* eslint-disable no-param-reassign */
export const MusicComponent: React.FC<Props> = ({
music,
setPlaying,
setCurrentPlaying,
}: Props) => {
const musicArray = useMemo(
() => music.map((sound) => soundLoad(sound, UI_MUSIC_VOLUME)),
[music]
);
useEffect(() => {
musicArray.forEach(sound => {
musicArray.forEach((sound) => {
sound.audio.onplay = () => {
setPlaying(true)
setCurrentPlaying(sound)
}
setPlaying(true);
setCurrentPlaying(sound);
};
sound.audio.onended = () => {
musicArray[randomNumber(0, musicArray.length)].playMusic()
}
})
setCurrentPlaying(musicArray[randomNumber(0, musicArray.length)])
musicArray[randomNumber(0, musicArray.length)].playMusic();
};
});
setCurrentPlaying(musicArray[randomNumber(0, musicArray.length)]);
return () => {
musicArray.forEach(({ audio }) => {
audio.onplay = null
audio.onended = null
audio.pause()
audio.currentTime = 0
})
setCurrentPlaying(undefined)
}
}, [musicArray, setPlaying, setCurrentPlaying])
audio.onplay = null;
audio.onended = null;
audio.pause();
audio.currentTime = 0;
});
setCurrentPlaying(undefined);
};
}, [musicArray, setPlaying, setCurrentPlaying]);
return null
}
return null;
};
MusicComponent.displayName = 'MusicComponent'
MusicComponent.displayName = "MusicComponent";
@@ -5,44 +5,44 @@ $panelHeight: $previewHeight + 40px;
$panelBorderSize: 8px;
.panel {
z-index: 2;
padding: 20px;
border: none;
position: absolute;
height: $panelHeight;
z-index: 2;
width: $panelWidth;
height: $panelHeight;
padding: 20px;
background-image: $panelBackground;
background-repeat: repeat;
border: none;
&-content {
display: flex;
justify-content: flex-start;
align-items: center;
justify-content: flex-start;
}
button {
z-index: 3;
position: absolute;
z-index: 3;
}
&--bottom {
bottom: -$panelHeight + $panelBorderSize;
width: 100%;
transition: bottom $transitionDuration $transitionType;
border-top: $panelBorderSize double $fontColor;
border-image: $borderTop 16 32 16 32;
border-image-outset: $panelBorderSize - 2px 0 0 0;
border-image-width: $panelBorderSize * 2 0 0 100%;
border-image-outset: $panelBorderSize - 2px 0 0 0;
border-image-repeat: round round;
transition: bottom $transitionDuration $transitionType;
.panel-content {
height: 100%;
}
button {
top: -$buttonHeight - 5px;
left: 50%;
transform: translateX(-50%);
top: -$buttonHeight - 5px;
}
&--shown {
@@ -55,8 +55,8 @@ $panelBorderSize: 8px;
height: 100%;
border-right: $panelBorderSize double $fontColor;
border-image: $borderRight 32 16 0 0;
border-image-outset: 0 $panelBorderSize - 2px 0 0;
border-image-width: 100% $panelBorderSize*2 0 0;
border-image-outset: 0 $panelBorderSize - 2px 0 0;
transition: left $transitionDuration $transitionType;
.panel-content {
@@ -66,8 +66,8 @@ $panelBorderSize: 8px;
button {
top: 50%;
transform: translateY(-50%) rotate(90deg);
right: -80px;
transform: translateY(-50%) rotate(90deg);
}
&--shown {
+165 -150
View File
@@ -1,4 +1,4 @@
import * as React from 'react'
import * as React from "react";
import {
FocusEvent,
MouseEvent,
@@ -8,185 +8,199 @@ import {
useMemo,
useRef,
useState,
WheelEvent
} from 'react'
import cn from 'classnames'
WheelEvent,
} from "react";
import cn from "classnames";
import { ANIMATION_DURATION, debounce, PREVIEW_HEIGHT, PREVIEW_WIDTH, SPACE } from '../../utils'
import { useSettings } from '../../hooks'
import {
ANIMATION_DURATION,
debounce,
PREVIEW_HEIGHT,
PREVIEW_WIDTH,
SPACE,
} from "../../utils";
import { useSettings } from "../../hooks";
import './panel-component.scss'
import "./panel-component.scss";
interface Props {
orientation: 'bottom' | 'left'
isShown: boolean
itemsCount: number
setShown: () => void
openSoundPlay: (volume?: number) => void
closeSoundPlay: (volume?: number) => void
children: React.ReactNode
orientation: "bottom" | "left";
isShown: boolean;
itemsCount: number;
setShown: () => void;
openSoundPlay: (volume?: number) => void;
closeSoundPlay: (volume?: number) => void;
children: React.ReactNode;
}
export const PanelComponent = ({
export const PanelComponent: React.FC<Props> = ({
isShown,
setShown,
children,
openSoundPlay,
closeSoundPlay,
itemsCount,
orientation
orientation,
}: Props) => {
const {settings: {language, uiSound}} = useSettings()
const [isDrag, setDrag] = useState(false)
const [trackPosition, setTrackPosition] = useState(0)
const [position, setPosition] = useState(0)
const [lastPosition, setLastPosition] = useState(0)
const {
settings: { language, uiSound },
} = useSettings();
const [isDrag, setDrag] = useState(false);
const [trackPosition, setTrackPosition] = useState(0);
const [position, setPosition] = useState(0);
const [lastPosition, setLastPosition] = useState(0);
const panel = useRef<HTMLInputElement>(null)
const isBottom = useMemo(() => orientation === 'bottom', [orientation])
const handleClick = (event: MouseEvent) => {
event.preventDefault()
setShown()
if (!uiSound) {
return
}
if (isShown) {
openSoundPlay()
} else {
closeSoundPlay()
}
}
const resetPanel = useCallback((animate = true) => {
if (!panel.current) {
return
}
if (animate) {
panel.current.style.transition = `transform 0.5s`
}
panel.current.style.transform = `unset`
setTrackPosition(0)
setPosition(0)
setLastPosition(0)
}, [panel])
useEffect(() => {
let timeout: NodeJS.Timeout
const handleResize = debounce(() => {
resetPanel()
timeout = setTimeout(() => {
if (!panel || !panel.current) {
return
}
panel.current.style.transition = 'unset'
}, ANIMATION_DURATION)
}, 100)
window.addEventListener('resize', handleResize)
return () => {
if (timeout) {
clearTimeout(timeout)
}
window.removeEventListener('resize', handleResize)
}
}, [panel, resetPanel])
useEffect(() => {
if (!isShown) {
resetPanel(false)
}
}, [isShown, resetPanel])
const handleMouseMove = (e: MouseEvent) => {
if (!isDrag) {
return
}
const overflow = windowOverflow()
if (!overflow) {
return
}
const {clientX, clientY} = e
const value = isBottom ? clientX : clientY
const diff = limiter(value, overflow)
setPosition(diff)
changePosition()
}
const panel = useRef<HTMLInputElement>(null);
const isBottom = useMemo(() => orientation === "bottom", [orientation]);
const windowOverflow = () => {
const {innerWidth, innerHeight} = window
const windowSize = isBottom ? innerWidth : innerHeight
const containerSize = itemsCount * ((isBottom ? PREVIEW_WIDTH : PREVIEW_HEIGHT) + 15)
const { innerWidth, innerHeight } = window;
const windowSize = isBottom ? innerWidth : innerHeight;
const containerSize =
itemsCount * ((isBottom ? PREVIEW_WIDTH : PREVIEW_HEIGHT) + 15);
if (!(containerSize > windowSize)) {
return 0
}
return Math.abs(containerSize - windowSize)
}
const limiter = (value: number, overflow: number, isWheel: boolean = false) => {
let diff = (!isWheel ? trackPosition : 0) - value + lastPosition
if (Math.abs(diff) > overflow + SPACE) {
diff = overflow + SPACE
} else if (diff < 0) {
diff = 0
}
return diff
return 0;
}
return Math.abs(containerSize - windowSize);
};
const changePosition = () => {
if (!panel.current) {
return
return;
}
panel.current.style.transform = `translate${isBottom ? 'X' : 'Y'}(${-position}px)`
panel.current.style.transform = `translate${
isBottom ? "X" : "Y"
}(${-position}px)`;
};
const limiter = (value: number, overflow: number, isWheel = false) => {
let diff = (!isWheel ? trackPosition : 0) - value + lastPosition;
if (Math.abs(diff) > overflow + SPACE) {
diff = overflow + SPACE;
} else if (diff < 0) {
diff = 0;
}
return diff;
};
const handleClick = (event: MouseEvent) => {
event.preventDefault();
setShown();
if (!uiSound) {
return;
}
if (isShown) {
openSoundPlay();
} else {
closeSoundPlay();
}
};
const resetPanel = useCallback(
(animate = true) => {
if (!panel.current) {
return;
}
if (animate) {
panel.current.style.transition = `transform 0.5s`;
}
panel.current.style.transform = `unset`;
setTrackPosition(0);
setPosition(0);
setLastPosition(0);
},
[panel]
);
useEffect(() => {
let timeout: NodeJS.Timeout;
const handleResize = debounce(() => {
resetPanel();
timeout = setTimeout(() => {
if (!panel || !panel.current) {
return;
}
panel.current.style.transition = "unset";
}, ANIMATION_DURATION);
}, 100);
window.addEventListener("resize", handleResize);
return () => {
if (timeout) {
clearTimeout(timeout);
}
window.removeEventListener("resize", handleResize);
};
}, [panel, resetPanel]);
useEffect(() => {
if (!isShown) {
resetPanel(false);
}
}, [isShown, resetPanel]);
const handleMouseMove = (e: MouseEvent) => {
if (!isDrag) {
return;
}
const overflow = windowOverflow();
if (!overflow) {
return;
}
const { clientX, clientY } = e;
const value = isBottom ? clientX : clientY;
const diff = limiter(value, overflow);
setPosition(diff);
changePosition();
};
const handleMouseDown = (e: MouseEvent) => {
const {clientX, clientY} = e
e.nativeEvent.stopImmediatePropagation()
setTrackPosition(isBottom ? clientX : clientY)
setDrag(true)
}
const { clientX, clientY } = e;
e.nativeEvent.stopImmediatePropagation();
setTrackPosition(isBottom ? clientX : clientY);
setDrag(true);
};
const handleTouchstart = (e: TouchEvent) => {
const {touches} = e
e.nativeEvent.stopImmediatePropagation()
setTrackPosition(isBottom ? touches[0].clientX : touches[0].clientY)
setDrag(true)
}
const { touches } = e;
e.nativeEvent.stopImmediatePropagation();
setTrackPosition(isBottom ? touches[0].clientX : touches[0].clientY);
setDrag(true);
};
const handleTouchMove = (e: TouchEvent) => {
const {touches} = e
const {clientX, clientY} = touches[0]
const overflow = windowOverflow()
const { touches } = e;
const { clientX, clientY } = touches[0];
const overflow = windowOverflow();
if (!overflow) {
return
return;
}
const value = isBottom ? clientX : clientY
const diff = limiter(value, overflow)
setPosition(diff)
changePosition()
}
const value = isBottom ? clientX : clientY;
const diff = limiter(value, overflow);
setPosition(diff);
changePosition();
};
const handleFree = (e: MouseEvent | FocusEvent | TouchEvent) => {
e.nativeEvent.stopImmediatePropagation()
setDrag(false)
setLastPosition(position)
}
e.nativeEvent.stopImmediatePropagation();
setDrag(false);
setLastPosition(position);
};
const handleScroll = (e: WheelEvent) => {
const {deltaY} = e
const overflow = windowOverflow()
const { deltaY } = e;
const overflow = windowOverflow();
if (!overflow) {
return
return;
}
const value = deltaY > 0 ? -80 : 80
const diff = limiter(value, overflow, true)
setPosition(diff)
changePosition()
setLastPosition(position)
}
const value = deltaY > 0 ? -80 : 80;
const diff = limiter(value, overflow, true);
setPosition(diff);
changePosition();
setLastPosition(position);
};
return (
<div
@@ -199,19 +213,20 @@ export const PanelComponent = ({
onMouseLeave={handleFree}
onWheel={handleScroll}
onBlur={handleFree}
className={cn('panel', `panel--${orientation}`, {[`panel--${orientation}--shown`]: isShown})}
>
<div
ref={panel}
className='panel-content'
className={cn("panel", `panel--${orientation}`, {
[`panel--${orientation}--shown`]: isShown,
})}
>
<div ref={panel} className="panel-content">
{isShown && children}
</div>
<button onClick={handleClick}>
{orientation === 'bottom' ? language['ui.button.views'] : language['ui.button.places']}
{orientation === "bottom"
? language["ui.button.views"]
: language["ui.button.places"]}
</button>
</div>
)
}
);
};
PanelComponent.displayName = 'PanelComponent'
PanelComponent.displayName = "PanelComponent";
@@ -7,28 +7,28 @@ $previewNameWidth: 250px;
$previewNameHeight: 25px;
.preview {
z-index: 4;
position: relative;
cursor: $cursorInteract, auto;
z-index: 4;
min-width: $previewWidth;
min-height: $previewHeight;
margin: 5px;
background-repeat: no-repeat;
background-position: center;
background-size: $previewWidth $previewHeight;
border: $previewBorderWidth double $fontColor;
border-image: $border 12 12 11 12;
border-image-outset: $previewBorderWidth / 2;
border-image-repeat: stretch stretch;
background-position: center;
background-size: $previewWidth $previewHeight;
background-repeat: no-repeat;
cursor: $cursorInteract, auto;
opacity: 1;
transition: opacity $transitionDuration $transitionType;
&-name {
position: absolute;
width: $previewNameWidth;
height: $previewNameHeight;
bottom: -$previewNameHeight + 5px;
left: 50%;
width: $previewNameWidth;
height: $previewNameHeight;
transform: translateX(-50%);
}
@@ -37,16 +37,16 @@ $previewNameHeight: 25px;
}
&--loading {
opacity: 0.4;
opacity: .4;
}
&:hover {
box-shadow: $hoverBox;
.preview-name {
box-shadow: -4px 4px 4px 2px $hoverColor,
box-shadow:
-4px 4px 4px 2px $hoverColor,
4px 0 4px 2px $hoverColor;
}
}
}
@@ -1,66 +1,77 @@
import * as React from 'react'
import { useCallback, useEffect, useMemo, useState } from 'react'
import cn from 'classnames'
import * as React from "react";
import { useCallback, useEffect, useMemo, useState } from "react";
import cn from "classnames";
import { useSettings } from '../../hooks'
import { Plug } from '../../assets'
import './preview-component.scss'
import { BorderedHeader } from '..'
import { useSettings } from "../../hooks";
import { Plug } from "../../assets";
import "./preview-component.scss";
import { BorderedHeader } from "..";
interface Props {
name?: string
isLoading: boolean
src: string
value: number
handleChange: (value: number) => void
name?: string;
isLoading: boolean;
src: string;
value: number;
handleChange: (value: number) => void;
}
export const PreviewComponent = ({name = '', src, value, handleChange, isLoading}: Props) => {
const {settings: {language}} = useSettings()
const [isLoaded, setLoaded] = useState(false)
export const PreviewComponent: React.FC<Props> = ({
name = "",
src,
value,
handleChange,
isLoading,
}: Props) => {
const {
settings: { language },
} = useSettings();
const [isLoaded, setLoaded] = useState(false);
const image = useMemo(() => {
setLoaded(false)
const img = new Image()
img.src = src
return img
}, [src])
setLoaded(false);
const img = new Image();
img.src = src;
return img;
}, [src]);
useEffect(() => {
image.onload = () => {
setLoaded(true)
}
setLoaded(true);
};
return () => {
image.onload = null
}
}, [image])
image.onload = null;
};
}, [image]);
const handleClick = useCallback((e: React.MouseEvent) => {
e.preventDefault()
handleChange(value)
}, [handleChange, value])
const handleClick = useCallback(
(e: React.MouseEvent) => {
e.preventDefault();
handleChange(value);
},
[handleChange, value]
);
return (
<div
onContextMenu={handleClick}
onClick={handleClick}
style={{
margin: `${name ? '10px 5px' : '5px'}`,
backgroundImage: `url(${isLoaded ? image.src : Plug})`
margin: `${name ? "10px 5px" : "5px"}`,
backgroundImage: `url(${isLoaded ? image.src : Plug})`,
}}
className={cn('preview', {
'preview--not-loaded': !isLoaded,
'preview--loading': isLoading
className={cn("preview", {
"preview--not-loaded": !isLoaded,
"preview--loading": isLoading,
})}
>
{name && (
<div className='preview-name'>
<div className="preview-name">
<BorderedHeader>
{language[name as keyof typeof language]}
</BorderedHeader>
</div>
)}
</div>
)
}
);
};
PreviewComponent.displayName = 'PreviewComponent'
PreviewComponent.displayName = "PreviewComponent";
@@ -5,23 +5,23 @@ $rangeHeight: 3px;
.range {
position: relative;
height: $rangeHeight;
width: $rangeWidth;
border: 3px double $fontColor;
border-image: $rangeBorder 5 5 5 5;
height: $rangeHeight;
background: $rangeBackground center repeat;
border: 3px double $fontColor;
border-radius: 6px;
border-image: $rangeBorder 5 5 5 5;
border-image-width: 4px;
border-image-outset: 2px 0;
border-image-repeat: round round;
border-radius: 6px;
&-stick {
position: absolute;
top: 50%;
left: 0;
width: 32px;
height: 32px;
background-image: $range;
left: 0;
top: 50%;
transform: translate(0, -50%);
}
@@ -1,123 +1,145 @@
import * as React from 'react'
import { KeyboardEvent, useCallback, useEffect, useRef, useState, WheelEvent } from 'react'
import * as React from "react";
import {
KeyboardEvent,
useCallback,
useEffect,
useRef,
useState,
WheelEvent,
} from "react";
import './range-component.scss'
import "./range-component.scss";
interface Props {
handleChange: (value: number) => void
defaultValue: number
handleChange: (value: number) => void;
defaultValue: number;
}
const MAX = 55
const MAX = 55;
export const RangeComponent = ({handleChange, defaultValue}: Props) => {
const [isPressed, setPressed] = useState(false)
const [position, setPosition] = useState(defaultValue * MAX)
export const RangeComponent: React.FC<Props> = ({
handleChange,
defaultValue,
}: Props) => {
const [isPressed, setPressed] = useState(false);
const [position, setPosition] = useState(defaultValue * MAX);
const stick = useRef<HTMLDivElement>(null)
const stick = useRef<HTMLDivElement>(null);
const handleFocus = useCallback(() => setPressed(true), [])
const handleFree = useCallback(() => setPressed(false), [])
const handleFocus = useCallback(() => setPressed(true), []);
const handleFree = useCallback(() => setPressed(false), []);
const limiter = (value: number, width: number) => {
let diff = value;
if (diff > width - 35) {
diff = MAX;
} else if (diff < 0) {
diff = 0;
}
return diff;
};
const handleKeyDown = (e: KeyboardEvent) => {
if (!stick || !stick.current || !stick.current.parentNode) {
return
return;
}
const {width} = (stick.current.parentNode as HTMLDivElement).getBoundingClientRect()
const handleChangePosition = (value: number): void => {
setPosition(value);
handleChange(value / MAX);
};
const { width } = (stick.current
.parentNode as HTMLDivElement).getBoundingClientRect();
switch (e.keyCode) {
case 37:
const minusValue = position - 5
const minusDiff = limiter(minusValue, width)
setPosition(minusDiff)
handleChange(minusDiff / MAX)
break
handleChangePosition(limiter(position - 5, width));
break;
case 39:
const plusValue = position + 5
const plusDiff = limiter(plusValue, width)
setPosition(plusDiff)
handleChange(plusDiff / MAX)
break
}
handleChangePosition(limiter(position + 5, width));
break;
default:
break;
}
};
const handlePoint = useCallback((e: React.MouseEvent | MouseEvent) => {
const handlePoint = useCallback(
(e: React.MouseEvent | MouseEvent) => {
if (!stick || !stick.current || !stick.current.parentNode) {
return
return;
}
const {width, left} = (stick.current.parentNode as HTMLDivElement).getBoundingClientRect()
const {clientX} = e
const value = clientX - left - 20
const diff = limiter(value, width)
const { width, left } = (stick.current
.parentNode as HTMLDivElement).getBoundingClientRect();
const { clientX } = e;
const value = clientX - left - 20;
const diff = limiter(value, width);
setPosition(diff)
handleChange(diff / MAX)
}, [stick, handleChange])
setPosition(diff);
handleChange(diff / MAX);
},
[stick, handleChange]
);
const handleMouseMove = useCallback((e: MouseEvent) => {
const handleMouseMove = useCallback(
(e: MouseEvent) => {
if (!isPressed) {
return
return;
}
handlePoint(e)
}, [isPressed, handlePoint])
handlePoint(e);
},
[isPressed, handlePoint]
);
const handleTouchMove = useCallback((e: TouchEvent) => {
const handleTouchMove = useCallback(
(e: TouchEvent) => {
if (!isPressed) {
return
return;
}
const {touches} = e
const {clientX} = touches[0]
const { touches } = e;
const { clientX } = touches[0];
if (!stick || !stick.current || !stick.current.parentNode) {
return
return;
}
const {width, left} = (stick.current.parentNode as HTMLDivElement).getBoundingClientRect()
const { width, left } = (stick.current
.parentNode as HTMLDivElement).getBoundingClientRect();
const value = clientX - left - 20
const diff = limiter(value, width)
const value = clientX - left - 20;
const diff = limiter(value, width);
setPosition(diff)
handleChange(diff / MAX)
}, [isPressed, stick, handleChange])
setPosition(diff);
handleChange(diff / MAX);
},
[isPressed, stick, handleChange]
);
const handleScroll = (e: WheelEvent) => {
if (!stick || !stick.current || !stick.current.parentNode) {
return
return;
}
const range = stick.current.parentNode as HTMLDivElement
const {width} = range.getBoundingClientRect()
range.focus()
const {deltaY} = e
const value = position + (deltaY > 0 ? -5 : 5)
const diff = limiter(value, width)
const range = stick.current.parentNode as HTMLDivElement;
const { width } = range.getBoundingClientRect();
range.focus();
const { deltaY } = e;
const value = position + (deltaY > 0 ? -5 : 5);
const diff = limiter(value, width);
setPosition(diff)
handleChange(diff / MAX)
}
const limiter = (value: number, width: number) => {
let diff = value
if (diff > width - 35) {
diff = MAX
} else if (diff < 0) {
diff = 0
}
return diff
}
setPosition(diff);
handleChange(diff / MAX);
};
useEffect(() => {
window.addEventListener('mousemove', handleMouseMove)
window.addEventListener('mouseup', handleFree)
window.addEventListener('touchmove', handleTouchMove)
window.addEventListener('touchend', handleFree)
window.addEventListener("mousemove", handleMouseMove);
window.addEventListener("mouseup", handleFree);
window.addEventListener("touchmove", handleTouchMove);
window.addEventListener("touchend", handleFree);
return () => {
window.removeEventListener('mousemove', handleMouseMove)
window.removeEventListener('mouseup', handleFree)
window.removeEventListener('touchmove', handleTouchMove)
window.removeEventListener('touchend', handleFree)
}
}, [handleMouseMove, handleTouchMove, handleFree])
window.removeEventListener("mousemove", handleMouseMove);
window.removeEventListener("mouseup", handleFree);
window.removeEventListener("touchmove", handleTouchMove);
window.removeEventListener("touchend", handleFree);
};
}, [handleMouseMove, handleTouchMove, handleFree]);
return (
<div
@@ -127,17 +149,17 @@ export const RangeComponent = ({handleChange, defaultValue}: Props) => {
onClick={handlePoint}
onTouchStart={handleFocus}
onWheel={handleScroll}
className='range'
className="range"
>
<div
ref={stick}
style={{
left: `${position}px`
left: `${position}px`,
}}
className='range-stick'
className="range-stick"
/>
</div>
)
}
);
};
RangeComponent.displayName = 'RangeComponent'
RangeComponent.displayName = "RangeComponent";
@@ -10,30 +10,30 @@ $DropDownBorder: 10px;
$dropDownOutset: $DropDownBorder / 2;
.select {
color: $fontColorWhite;
display: flex;
position: relative;
padding-left: 6px;
justify-content: space-between;
border-radius: 8px;
display: flex;
align-items: center;
justify-content: space-between;
width: $selectWidth;
height: $selectHeight;
padding-left: 6px;
color: $fontColorWhite;
background-image: $selectBorder;
background-repeat: no-repeat;
background-size: $selectBackgroundWidth $selectBackgroundHeight;
background-position: center top;
background-size: $selectBackgroundWidth $selectBackgroundHeight;
border-radius: 8px;
&::before {
z-index: -1;
content: '';
position: absolute;
top: 4px;
left: 2px;
z-index: -1;
width: 75px;
height: 18px;
background-image: $panelBackground;
background-repeat: repeat;
content: "";
}
&:active:not(.select--opened) {
@@ -54,22 +54,22 @@ $dropDownOutset: $DropDownBorder / 2;
}
&-drop-down {
z-index: 7;
position: absolute;
top: $selectHeight + 10px;
left: 50%;
z-index: 7;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
width: $selectWidth + 10px;
top: $selectHeight + 10px;
left: 50%;
transform: translateX(-50%);
background-color: $settingsBackground;
border: $dropDownOutset double $fontColor;
border-image: $border 13 13 13 13;
border-image-width: $DropDownBorder;
border-image-outset: $dropDownOutset;
border-image-repeat: stretch stretch;
background-color: $settingsBackground;
transform: translateX(-50%);
&:focus {
outline: none;
@@ -77,19 +77,22 @@ $dropDownOutset: $DropDownBorder / 2;
}
&-item {
width: 100%;
text-align: center;
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 20px;
text-align: center;
&:hover {
background: linear-gradient(90deg,
rgba(173, 154, 32, 0.1) 0%,
rgba(173, 154, 32, 0.5) 25%,
rgba(173, 154, 32, 0.5) 75%,
rgba(173, 154, 32, 0.1) 100%);
background:
linear-gradient(
90deg,
rgba(173, 154, 32, .1) 0%,
rgba(173, 154, 32, .5) 25%,
rgba(173, 154, 32, .5) 75%,
rgba(173, 154, 32, .1) 100%
);
}
&:active {
@@ -97,31 +100,34 @@ $dropDownOutset: $DropDownBorder / 2;
}
&:focus {
background:
linear-gradient(
90deg,
rgba(173, 154, 32, .1) 0%,
rgba(173, 154, 32, .5) 25%,
rgba(173, 154, 32, .5) 75%,
rgba(173, 154, 32, .1) 100%
);
outline: none;
background: linear-gradient(90deg,
rgba(173, 154, 32, 0.1) 0%,
rgba(173, 154, 32, 0.5) 25%,
rgba(173, 154, 32, 0.5) 75%,
rgba(173, 154, 32, 0.1) 100%);
}
&::before {
content: '';
position: absolute;
left: 0;
width: 16px;
height: 16px;
background: $radio;
left: 0;
content: "";
}
&--selected {
&::before {
content: '';
position: absolute;
left: 0;
width: 16px;
height: 16px;
background: $radio 48px, $radio;
left: 0;
content: "";
}
}
}
@@ -1,48 +1,63 @@
import * as React from 'react'
import { FocusEvent, KeyboardEvent, useCallback, useRef, useState } from 'react'
import cn from 'classnames'
import * as React from "react";
import {
FocusEvent,
KeyboardEvent,
useCallback,
useRef,
useState,
} from "react";
import cn from "classnames";
import './select-component.scss'
import "./select-component.scss";
interface Props {
children: React.ReactNode
options: any[]
current: any
handleChange: (value: any) => void
children: React.ReactNode;
options: string[];
current: unknown;
handleChange: (value: string) => void;
}
export const SelectComponent = ({children, options, current, handleChange}: Props) => {
const [isSelectShown, setSelectShown] = useState(false)
const dropDownRef = useRef<HTMLDivElement>(null)
export const SelectComponent: React.FC<Props> = ({
children,
options,
current,
handleChange,
}: Props) => {
const [isSelectShown, setSelectShown] = useState(false);
const dropDownRef = useRef<HTMLDivElement>(null);
const handleSelectClick = useCallback(() => setSelectShown(!isSelectShown), [isSelectShown])
const handleSelectClick = useCallback(() => setSelectShown(!isSelectShown), [
isSelectShown,
]);
const handleBlur = (e: FocusEvent) => {
if (!dropDownRef || !dropDownRef.current) {
return
return;
}
if (dropDownRef.current.contains(e.relatedTarget as Node) ||
e.currentTarget === e.relatedTarget) {
return
}
setSelectShown(!isSelectShown)
if (
dropDownRef.current.contains(e.relatedTarget as Node) ||
e.currentTarget === e.relatedTarget
) {
return;
}
setSelectShown(!isSelectShown);
};
const handleKeyDown = (e: KeyboardEvent) => {
if (e.keyCode !== 13 && e.keyCode !== 32) {
return
}
setSelectShown(!isSelectShown)
return;
}
setSelectShown(!isSelectShown);
};
const onItemClick = (itemValue: any) => handleChange(itemValue)
const onItemClick = (itemValue: string) => handleChange(itemValue);
const onItemKeyDown = (e: KeyboardEvent, itemValue: any) => {
const onItemKeyDown = (e: KeyboardEvent, itemValue: string) => {
if (e.keyCode !== 13 && e.keyCode !== 32) {
return
}
handleChange(itemValue)
return;
}
handleChange(itemValue);
};
return (
<div
@@ -50,25 +65,22 @@ export const SelectComponent = ({children, options, current, handleChange}: Prop
onKeyDown={handleKeyDown}
onBlur={handleBlur}
tabIndex={0}
className={cn('select', {
'select--opened': isSelectShown
className={cn("select", {
"select--opened": isSelectShown,
})}
>
{children}
<div className='select-arrow' />
<div className="select-arrow" />
{isSelectShown && (
<div
ref={dropDownRef}
className='select-drop-down'
>
<div ref={dropDownRef} className="select-drop-down">
{options.map((item, index) => (
<div
key={index}
tabIndex={0}
onClick={() => onItemClick(item)}
onKeyDown={(e) => onItemKeyDown(e, item)}
className={cn('select-item', {
'select-item--selected': item === current
className={cn("select-item", {
"select-item--selected": item === current,
})}
>
{item}
@@ -77,7 +89,7 @@ export const SelectComponent = ({children, options, current, handleChange}: Prop
</div>
)}
</div>
)
}
);
};
SelectComponent.displayName = 'SelectComponent'
SelectComponent.displayName = "SelectComponent";
@@ -9,45 +9,45 @@ $settingsHeaderWidth: 132px;
$settingsHeaderHeight: 25px;
.settings {
z-index: 5;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
left: 50%;
z-index: 5;
width: $settingsWidth;
height: $settingsHeight;
font-size: $fontSize;
font-family: $font;
letter-spacing: $fontSpacing;
text-shadow: $fontShadow;
background-color: $settingsBackground;
border: $settingsBorderWidth double $fontColor;
border-image: $border 15 15 15 15 fill;
border-image-outset: $settingsBorderOutset;
border-image-repeat: stretch stretch;
font-family: $font;
font-size: $fontSize;
text-shadow: $fontShadow;
letter-spacing: $fontSpacing;
width: $settingsWidth;
height: $settingsHeight;
background-color: $settingsBackground;
transform: translate(-50%, -50%);
&-header {
z-index: 6;
position: absolute;
left: 50%;
transform: translateX(-50%);
top: -$settingsHeaderHeight;
left: 50%;
z-index: 6;
width: $settingsHeaderWidth;
height: $settingsHeaderHeight;
transform: translateX(-50%);
}
&-content {
color: $fontColor;
margin-top: 10px;
display: grid;
grid-template-rows: 1fr;
grid-gap: 15px;
grid-template-rows: 1fr;
margin-top: 10px;
color: $fontColor;
}
&-option {
display: flex;
justify-content: space-between;
align-items: center;
justify-content: space-between;
}
.settings-button {
@@ -1,118 +1,132 @@
import * as React from 'react'
import * as React from "react";
import ru from '../../locales/ru.json'
import en from '../../locales/en.json'
import { useSettings } from '../../hooks'
import { Settings } from '../../settings-context'
import { BorderedHeader, CheckBoxComponent, RangeComponent, SelectComponent } from '..'
import ru from "../../locales/ru.json";
import en from "../../locales/en.json";
import { useSettings } from "../../hooks";
import { Settings } from "../../settings-context";
import {
BorderedHeader,
CheckBoxComponent,
RangeComponent,
SelectComponent,
} from "..";
import './settings-component.scss'
import "./settings-component.scss";
interface Props {
closeSettings: () => void
checkboxOnSoundPlay: (volume?: number) => void
checkboxOffSoundPlay: (volume?: number) => void
closeSettings: () => void;
checkboxOnSoundPlay: (volume?: number) => void;
checkboxOffSoundPlay: (volume?: number) => void;
}
export const SettingsComponent = ({closeSettings, checkboxOnSoundPlay, checkboxOffSoundPlay}: Props) => {
const {settings, saveSettings} = useSettings()
/* eslint-disable no-unused-expressions */
export const SettingsComponent: React.FC<Props> = ({
closeSettings,
checkboxOnSoundPlay,
checkboxOffSoundPlay,
}: Props) => {
const { settings, saveSettings } = useSettings();
const handleCheckboxClick = (option: keyof Settings) => {
saveSettings!({...settings, [option]: !settings[option]})
saveSettings?.({ ...settings, [option]: !settings[option] });
if (!settings.uiSound) {
return
return;
}
if (settings[option]) {
checkboxOffSoundPlay()
checkboxOffSoundPlay();
} else {
checkboxOnSoundPlay()
}
checkboxOnSoundPlay();
}
};
const handleChangeLanguage = (nextLanguage: string) => {
if (settings.currentLanguage === nextLanguage) {
return
return;
}
if (nextLanguage === ru['ui.language']) {
saveSettings!({...settings, language: ru, currentLanguage: nextLanguage})
if (nextLanguage === ru["ui.language"]) {
saveSettings?.({
...settings,
language: ru,
currentLanguage: nextLanguage,
});
} else {
saveSettings!({...settings, language: en, currentLanguage: nextLanguage})
saveSettings?.({
...settings,
language: en,
currentLanguage: nextLanguage,
});
}
if (!settings.uiSound) {
return
}
checkboxOnSoundPlay()
return;
}
checkboxOnSoundPlay();
};
const handleChangeRange = (value: number) => {
checkboxOnSoundPlay()
saveSettings!({...settings, musicVolume: value})
}
checkboxOnSoundPlay();
saveSettings?.({ ...settings, musicVolume: value });
};
const chooseOption = (option: keyof Settings) => {
const {language} = settings
const chooseOption = (option: keyof Settings): React.ReactNode => {
const { language } = settings;
switch (typeof settings[option]) {
case 'boolean':
case "boolean":
return (
<CheckBoxComponent
handleClick={handleCheckboxClick}
optionName={option}
value={settings[option] as boolean}
/>
)
case 'object':
);
case "object":
return (
<SelectComponent
handleChange={handleChangeLanguage}
current={language['ui.language']}
current={language["ui.language"]}
options={settings[option] as []}
>
{language['ui.language']}
{language["ui.language"]}
</SelectComponent>
)
case 'number':
);
case "number":
return (
<RangeComponent
defaultValue={settings[option] as number}
handleChange={handleChangeRange}
/>
)
}
);
default:
return null;
}
};
const renderOption = (option: keyof Settings) => {
const {language} = settings
const valueName = `ui.${option}` as keyof typeof language
const { language } = settings;
const valueName = `ui.${option}` as keyof typeof language;
return (
<div className='settings-option'>
<div className='settings-option-name'>
{language[valueName]}
</div>
<div className="settings-option">
<div className="settings-option-name">{language[valueName]}</div>
{chooseOption(option)}
</div>
)
}
);
};
return (
<div className='settings'>
<div className='settings-header'>
<BorderedHeader>
{settings.language['ui.main-menu']}
</BorderedHeader>
<div className="settings">
<div className="settings-header">
<BorderedHeader>{settings.language["ui.main-menu"]}</BorderedHeader>
</div>
<div className='settings-content'>
{renderOption('uiLanguage')}
{renderOption('musicVolume')}
{renderOption('uiSound')}
<div className="settings-content">
{renderOption("uiLanguage")}
{renderOption("musicVolume")}
{renderOption("uiSound")}
</div>
<button
className='settings-button'
onClick={closeSettings}
>
{settings.language['ui.button.close']}
<button className="settings-button" onClick={closeSettings}>
{settings.language["ui.button.close"]}
</button>
</div>
)
}
);
};
SettingsComponent.displayName = 'SettingsComponent'
SettingsComponent.displayName = "SettingsComponent";
@@ -1,10 +1,10 @@
@import "../../app/style";
.view {
z-index: 1;
position: absolute;
top: 0;
left: 0;
z-index: 1;
min-width: 100vw;
min-height: 100vh;
background-repeat: no-repeat;
@@ -12,12 +12,12 @@
animation-direction: alternate;
&-background {
z-index: 2;
opacity: 1;
position: absolute;
z-index: 2;
min-width: inherit;
min-height: inherit;
background: $backgroundTexture;
opacity: 1;
transition: opacity $transitionDuration $transitionType;
&--loaded {
+106 -98
View File
@@ -1,155 +1,162 @@
import * as React from 'react'
import { FocusEvent, MouseEvent, TouchEvent, useCallback, useEffect, useState } from 'react'
import cn from 'classnames'
import * as React from "react";
import {
FocusEvent,
MouseEvent,
TouchEvent,
useCallback,
useEffect,
useState,
} from "react";
import cn from "classnames";
import { Background } from '../../assets'
import { ANIMATION_DURATION, DEFAULT_HEIGHT, DEFAULT_WIDTH } from '../../utils'
import { Background } from "../../assets";
import { ANIMATION_DURATION, DEFAULT_HEIGHT, DEFAULT_WIDTH } from "../../utils";
import './view-component.scss'
import "./view-component.scss";
interface Props {
src: string
src: string;
}
interface Position {
x: number
y: number
x: number;
y: number;
}
const initialPosition = {
x: 0,
y: 0
}
y: 0,
};
export const ViewComponent = ({src}: Props) => {
const [imageSrc, setImageSrc] = useState(Background)
const [isLoaded, setLoaded] = useState(false)
const [isDrag, setDrag] = useState(false)
const [trackPosition, setTrackPosition] = useState(initialPosition)
const [position, setPosition] = useState(initialPosition)
const [lastPosition, setLastPosition] = useState(initialPosition)
const [isBigScreen, setBigScreen] = useState(false)
export const ViewComponent: React.FC<Props> = ({ src }: Props) => {
const [imageSrc, setImageSrc] = useState(Background);
const [isLoaded, setLoaded] = useState(false);
const [isDrag, setDrag] = useState(false);
const [trackPosition, setTrackPosition] = useState(initialPosition);
const [position, setPosition] = useState(initialPosition);
const [lastPosition, setLastPosition] = useState(initialPosition);
const [isBigScreen, setBigScreen] = useState(false);
const handleResize = useCallback(() => {
const {innerWidth, innerHeight} = window
const { innerWidth, innerHeight } = window;
let width = 0
let height = 0
setBigScreen(false)
let width = 0;
let height = 0;
setBigScreen(false);
if (innerHeight < DEFAULT_HEIGHT && innerWidth < DEFAULT_WIDTH) {
width = (innerWidth - DEFAULT_WIDTH) / 2
height = (innerHeight - DEFAULT_HEIGHT) / 2
width = (innerWidth - DEFAULT_WIDTH) / 2;
height = (innerHeight - DEFAULT_HEIGHT) / 2;
} else {
setBigScreen(true)
setBigScreen(true);
}
setPosition({x: width, y: height})
setLastPosition({x: width, y: height})
}, [])
setPosition({ x: width, y: height });
setLastPosition({ x: width, y: height });
}, []);
useEffect(() => {
handleResize()
setLoaded(false)
handleResize();
setLoaded(false);
const timer = setTimeout(() => {
const image = new Image()
image.src = src
const image = new Image();
image.src = src;
image.onload = () => {
setImageSrc(src)
setLoaded(true)
}
}, ANIMATION_DURATION)
setImageSrc(src);
setLoaded(true);
};
}, ANIMATION_DURATION);
return () => {
clearTimeout(timer)
}
}, [src, handleResize])
clearTimeout(timer);
};
}, [src, handleResize]);
useEffect(() => {
window.addEventListener('resize', handleResize)
window.addEventListener("resize", handleResize);
return () => {
window.removeEventListener('resize', handleResize)
}
}, [handleResize])
const handleTouchMove = (e: TouchEvent) => {
const {touches} = e
if (isBigScreen) {
return
}
const {innerWidth, innerHeight} = window
const width = DEFAULT_WIDTH - innerWidth
const height = DEFAULT_HEIGHT - innerHeight
const {clientX: x, clientY: y} = touches[0]
const diff = limiter({x, y}, width, height)
setPosition(diff)
}
window.removeEventListener("resize", handleResize);
};
}, [handleResize]);
const limiter = (value: Position, width: number, height: number) => {
const {x: xValue, y: yValue} = value
const { x: xValue, y: yValue } = value;
let x = lastPosition.x - trackPosition.x + xValue
let y = lastPosition.y - trackPosition.y + yValue
let x = lastPosition.x - trackPosition.x + xValue;
let y = lastPosition.y - trackPosition.y + yValue;
if (x > 0) {
x = 0
x = 0;
} else if (x < -width) {
x = -width
x = -width;
}
if (y > 0) {
y = 0
y = 0;
} else if (y < -height) {
y = -height
y = -height;
}
return ({x, y})
return { x, y };
};
const handleTouchMove = (e: TouchEvent) => {
const { touches } = e;
if (isBigScreen) {
return;
}
const { innerWidth, innerHeight } = window;
const width = DEFAULT_WIDTH - innerWidth;
const height = DEFAULT_HEIGHT - innerHeight;
const { clientX: x, clientY: y } = touches[0];
const diff = limiter({ x, y }, width, height);
setPosition(diff);
};
const handleTouchstart = (e: TouchEvent) => {
const {touches} = e
e.nativeEvent.stopImmediatePropagation()
const {clientX: x, clientY: y} = touches[0]
setTrackPosition({x, y})
setDrag(true)
}
const { touches } = e;
e.nativeEvent.stopImmediatePropagation();
const { clientX: x, clientY: y } = touches[0];
setTrackPosition({ x, y });
setDrag(true);
};
const handleMouseDown = (e: MouseEvent) => {
const {clientX, clientY} = e
e.nativeEvent.stopImmediatePropagation()
setTrackPosition({x: clientX, y: clientY})
setDrag(true)
}
const { clientX, clientY } = e;
e.nativeEvent.stopImmediatePropagation();
setTrackPosition({ x: clientX, y: clientY });
setDrag(true);
};
const handleFree = (e: MouseEvent | FocusEvent | TouchEvent) => {
e.nativeEvent.stopImmediatePropagation()
setDrag(false)
setLastPosition(position)
}
e.nativeEvent.stopImmediatePropagation();
setDrag(false);
setLastPosition(position);
};
const handleMouseMove = (e: MouseEvent) => {
if (!isDrag) {
return
return;
}
if (isBigScreen) {
return
return;
}
const {innerWidth, innerHeight} = window
const width = DEFAULT_WIDTH - innerWidth
const height = DEFAULT_HEIGHT - innerHeight
const { innerWidth, innerHeight } = window;
const width = DEFAULT_WIDTH - innerWidth;
const height = DEFAULT_HEIGHT - innerHeight;
const {clientX: x, clientY: y} = e
const diff = limiter({x, y}, width, height)
setPosition(diff)
}
const { clientX: x, clientY: y } = e;
const diff = limiter({ x, y }, width, height);
setPosition(diff);
};
return (
<div
className='view'
className="view"
style={{
backgroundImage: `url(${imageSrc})`,
backgroundPosition: `${position.x}px ${position.y}px`,
backgroundSize: `${isBigScreen ? 'cover' : 'auto'}`
backgroundSize: `${isBigScreen ? "cover" : "auto"}`,
}}
onMouseDown={handleMouseDown}
onMouseMove={handleMouseMove}
@@ -160,12 +167,13 @@ export const ViewComponent = ({src}: Props) => {
onMouseLeave={handleFree}
onBlur={handleFree}
>
<div className={cn('view-background', {
'view-background--loaded': isLoaded
<div
className={cn("view-background", {
"view-background--loaded": isLoaded,
})}
/>
</div>
)
}
);
};
ViewComponent.displayName = 'ViewComponent'
ViewComponent.displayName = "ViewComponent";
+1 -1
View File
@@ -1 +1 @@
export { useSettings } from './use-settings'
export { useSettings } from "./use-settings";
+4 -3
View File
@@ -1,4 +1,5 @@
import { useContext } from 'react'
import SettingsContext from '../settings-context'
import { useContext } from "react";
import SettingsContext, { SettingsContextType } from "../settings-context";
export const useSettings = () => useContext(SettingsContext)
export const useSettings = (): SettingsContextType =>
useContext(SettingsContext);
+12 -12
View File
@@ -1,23 +1,23 @@
import * as React from 'react'
import ReactDom from 'react-dom'
import * as React from "react";
import ReactDom from "react-dom";
import { Settings, SettingsProvider } from './settings-context'
import App from './app'
import { Settings, SettingsProvider } from "./settings-context";
import App from "./app";
import ru from './locales/ru.json'
import en from './locales/en.json'
import ru from "./locales/ru.json";
import en from "./locales/en.json";
const defaultSettings: Settings = {
language: ru,
musicVolume: 1.0,
currentLanguage: ru['ui.language'],
uiLanguage: [ru['ui.language'], en['ui.language']],
uiSound: true
}
currentLanguage: ru["ui.language"],
uiLanguage: [ru["ui.language"], en["ui.language"]],
uiSound: true,
};
ReactDom.render(
<SettingsProvider settings={defaultSettings}>
<App />
</SettingsProvider>,
document.getElementById('root')
)
document.getElementById("root")
);
+32 -26
View File
@@ -1,43 +1,49 @@
/* eslint-disable no-console */
export default class Sound {
public audio: HTMLAudioElement
private volume: number
public audio: HTMLAudioElement;
private volume: number;
constructor(file: string, volumeValue?: number) {
const volume = this.validateVolume(volumeValue)
this.audio = new Audio(file)
this.audio.load()
this.volume = volume
const volume = this.validateVolume(volumeValue);
this.audio = new Audio(file);
this.audio.load();
this.volume = volume;
}
public setVolume = (volume: number) => {
this.validateVolume(volume)
this.volume = volume
public setVolume = (volume: number): Sound => {
this.validateVolume(volume);
this.volume = volume;
return this
}
return this;
};
public playSound = (volume: number = this.volume) => {
this.audio.volume = this.validateVolume(volume)
public playSound = (volume: number = this.volume): void => {
this.audio.volume = this.validateVolume(volume);
if (!this.audio.readyState) {
return
}
this.audio.play().catch((error: Error) => console.error(`Error playback: ${error}`))
return;
}
this.audio
.play()
.catch((error: Error) => console.error(`Error playback: ${error}`));
};
public playMusic = (volume: number = this.volume) => {
this.audio.volume = this.validateVolume(volume)
public playMusic = (volume: number = this.volume): void => {
this.audio.volume = this.validateVolume(volume);
if (!this.audio.readyState) {
return
}
this.audio.play().catch((error: Error) => console.error(`Error playback: ${error}`))
return;
}
this.audio
.play()
.catch((error: Error) => console.error(`Error playback: ${error}`));
};
public pause = () => this.audio.pause()
public pause = (): void => this.audio.pause();
private validateVolume = (volumeValue: number = 1.0) => {
private validateVolume = (volumeValue = 1.0) => {
if (volumeValue && (volumeValue < 0 || volumeValue > 1)) {
throw Error('"Volume" must be an number between 0.0 and 1.0')
}
return volumeValue
throw Error('"Volume" must be an number between 0.0 and 1.0');
}
return volumeValue;
};
}
+2 -2
View File
@@ -1,3 +1,3 @@
/// <reference types="react-scripts" />
declare module '*.ogg'
declare module '*.mp3'
declare module "*.ogg";
declare module "*.mp3";
+32 -27
View File
@@ -1,44 +1,49 @@
import * as React from 'react'
import { createContext, useState } from 'react'
import * as React from "react";
import { createContext, useState } from "react";
import ru from './locales/ru.json'
import en from './locales/en.json'
import ru from "./locales/ru.json";
import en from "./locales/en.json";
export interface Settings {
language: typeof ru | typeof en
musicVolume: number
currentLanguage: string
uiLanguage: string[]
uiSound: boolean
language: typeof ru | typeof en;
musicVolume: number;
currentLanguage: string;
uiLanguage: string[];
uiSound: boolean;
}
interface SettingsContextType {
settings: Settings
saveSettings?: (value: Settings) => void
export interface SettingsContextType {
settings: Settings;
saveSettings?: (value: Settings) => void;
}
interface Props {
children: React.ReactNode
settings: Settings
children: React.ReactNode;
settings: Settings;
}
const defaultSettings: SettingsContextType = {
settings: {
language: ru,
musicVolume: 1.0,
currentLanguage: ru['ui.language'],
uiLanguage: [ru['ui.language'], en['ui.language']],
uiSound: true
}
}
const SettingsContext = createContext(defaultSettings)
currentLanguage: ru["ui.language"],
uiLanguage: [ru["ui.language"], en["ui.language"]],
uiSound: true,
},
};
const SettingsContext = createContext(defaultSettings);
export const SettingsProvider = ({children, settings}: Props) => {
const [currentSettings, setCurrentSettings] = useState(settings || defaultSettings)
export const SettingsProvider: React.FC<Props> = ({
children,
settings,
}: Props) => {
const [currentSettings, setCurrentSettings] = useState(
settings || defaultSettings
);
const saveSettings = (value: Settings) => {
setCurrentSettings(value)
}
setCurrentSettings(value);
};
return (
<SettingsContext.Provider
@@ -46,7 +51,7 @@ export const SettingsProvider = ({children, settings}: Props) => {
>
{children}
</SettingsContext.Provider>
)
}
);
};
export default SettingsContext
export default SettingsContext;
+9 -9
View File
@@ -1,9 +1,9 @@
export const ANIMATION_DURATION = 500
export const LOADING_DURATION = 800
export const PREVIEW_WIDTH = 320
export const PREVIEW_HEIGHT = 180
export const UI_SOUND_VOLUME = 0.2
export const UI_MUSIC_VOLUME = 1
export const SPACE = 200
export const DEFAULT_WIDTH = 1920
export const DEFAULT_HEIGHT = 1080
export const ANIMATION_DURATION = 500;
export const LOADING_DURATION = 800;
export const PREVIEW_WIDTH = 320;
export const PREVIEW_HEIGHT = 180;
export const UI_SOUND_VOLUME = 0.2;
export const UI_MUSIC_VOLUME = 1;
export const SPACE = 200;
export const DEFAULT_WIDTH = 1920;
export const DEFAULT_HEIGHT = 1080;
+17 -17
View File
@@ -1,5 +1,5 @@
import { LOADING_DURATION } from './constants'
import Sound from '../modules/sound'
import { LOADING_DURATION } from "./constants";
import Sound from "../modules/sound";
export {
PREVIEW_WIDTH,
@@ -10,25 +10,25 @@ export {
ANIMATION_DURATION,
DEFAULT_HEIGHT,
DEFAULT_WIDTH,
SPACE
} from './constants'
SPACE,
} from "./constants";
export const delay = () => new Promise(resolve => setTimeout(resolve, LOADING_DURATION))
export const delay = (): Promise<unknown> =>
new Promise((resolve) => setTimeout(resolve, LOADING_DURATION));
export const soundLoad = (soundFile: string, soundVolume: number) => (
new Sound(soundFile, soundVolume)
)
export const soundLoad = (soundFile: string, soundVolume: number): Sound =>
new Sound(soundFile, soundVolume);
export const randomNumber = (min: number, max: number) => (
Math.floor(Math.random() * (max - min)) + min
)
export const randomNumber = (min: number, max: number): number =>
Math.floor(Math.random() * (max - min)) + min;
export function debounce(fn: (args: any) => any, ms: number) {
let timer: NodeJS.Timeout
return (...args: any) => {
// eslint-disable-next-line
export function debounce(fn: (args: any) => unknown, ms: number): any {
let timer: NodeJS.Timeout;
return (...args: [unknown]) => {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => fn.apply(this, args), ms)
clearTimeout(timer);
}
timer = setTimeout(() => fn.apply(this, args), ms);
};
}
-34
View File
@@ -1,34 +0,0 @@
{
"extends": "tslint:recommended",
"rules": {
"max-line-length": {
"options": [
120
]
},
"new-parens": true,
"no-arg": true,
"semicolon": false,
"no-bitwise": false,
"no-conditional-assignment": true,
"no-consecutive-blank-lines": true,
"no-console": {
"severity": "warning",
"options": [
"debug",
"info",
"log",
"time",
"timeEnd",
"trace"
]
}
},
"jsRules": {
"max-line-length": {
"options": [
120
]
}
}
}