chuijs 4.0.2 → 4.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +597 -0
- package/README.md +43 -644
- package/framework/appLayout/default/chui_app_layout.js +602 -496
- package/framework/appLayout/default/global_style.css +288 -97
- package/framework/appLayout/default/main_theme_style.css +188 -101
- package/framework/components/chui_accordion/accordion.js +38 -35
- package/framework/components/chui_accordion/styles.css +13 -12
- package/framework/components/chui_action_sheet/action_sheet.js +93 -64
- package/framework/components/chui_action_sheet/styles.css +12 -5
- package/framework/components/chui_actions_bar/actions_bar.js +338 -0
- package/framework/components/chui_actions_bar/styles.css +139 -0
- package/framework/components/chui_affix/affix.js +16 -11
- package/framework/components/chui_affix/styles.css +5 -0
- package/framework/components/chui_alert/alert.js +34 -19
- package/framework/components/chui_alert/styles.css +7 -0
- package/framework/components/chui_avatar/avatar.js +36 -35
- package/framework/components/chui_avatar/styles.css +1 -1
- package/framework/components/chui_avatar_group/avatar_group.js +25 -23
- package/framework/components/chui_avatar_group/styles.css +1 -1
- package/framework/components/chui_backtop/backtop.js +60 -21
- package/framework/components/chui_backtop/styles.css +21 -0
- package/framework/components/chui_badge/badge.js +30 -28
- package/framework/components/chui_badge/styles.css +6 -6
- package/framework/components/chui_banner/banner.js +222 -0
- package/framework/components/chui_banner/styles.css +170 -0
- package/framework/components/chui_breadcrumb/breadcrumb.js +15 -13
- package/framework/components/chui_breadcrumb/styles.css +1 -1
- package/framework/components/chui_button/button.js +52 -36
- package/framework/components/chui_button/styles.css +7 -7
- package/framework/components/chui_calendar/calendar.js +18 -16
- package/framework/components/chui_card/card.js +52 -32
- package/framework/components/chui_card_scroll/card_scroll.js +169 -0
- package/framework/components/chui_card_scroll/styles.css +86 -0
- package/framework/components/chui_chat/chat.js +140 -79
- package/framework/components/chui_chat/styles.css +18 -7
- package/framework/components/chui_clipboard_history/clipboard_history.js +53 -39
- package/framework/components/chui_clipboard_history/styles.css +13 -9
- package/framework/components/chui_code/code.js +10 -10
- package/framework/components/chui_code/styles.css +4 -4
- package/framework/components/chui_code_editor/code_editor.js +73 -57
- package/framework/components/chui_code_editor/styles.css +6 -5
- package/framework/components/chui_command_palette/command_palette.js +87 -64
- package/framework/components/chui_command_palette/styles.css +5 -5
- package/framework/components/chui_console/console.js +13 -13
- package/framework/components/chui_console/styles.css +6 -3
- package/framework/components/chui_content_block/content_block.js +35 -21
- package/framework/components/chui_content_block/styles.css +2 -2
- package/framework/components/chui_context_menu/context_menu.js +171 -58
- package/framework/components/chui_context_menu/styles.css +82 -8
- package/framework/components/chui_custom_element/custom_element.js +25 -18
- package/framework/components/chui_data_grid/data_grid.js +633 -471
- package/framework/components/chui_data_grid/styles.css +24 -22
- package/framework/components/chui_descriptions/descriptions.js +34 -17
- package/framework/components/chui_descriptions/styles.css +1 -1
- package/framework/components/chui_details/details.js +42 -36
- package/framework/components/chui_details/styles.css +12 -11
- package/framework/components/chui_diff_viewer/diff_viewer.js +172 -147
- package/framework/components/chui_diff_viewer/styles.css +10 -10
- package/framework/components/chui_divider/divider.js +19 -17
- package/framework/components/chui_divider/styles.css +2 -2
- package/framework/components/chui_drawer/drawer.js +63 -38
- package/framework/components/chui_drawer/styles.css +18 -4
- package/framework/components/chui_drop_zone/drop_zone.js +37 -27
- package/framework/components/chui_drop_zone/styles.css +10 -6
- package/framework/components/chui_empty_state/empty_state.js +20 -15
- package/framework/components/chui_fieldset/fieldset.js +40 -23
- package/framework/components/chui_fieldset/styles.css +6 -6
- package/framework/components/chui_file_explorer/file_explorer.js +260 -189
- package/framework/components/chui_file_explorer/styles.css +8 -7
- package/framework/components/chui_form/form.js +40 -28
- package/framework/components/chui_form/styles.css +1 -1
- package/framework/components/chui_gantt/gantt.js +102 -78
- package/framework/components/chui_gantt/styles.css +5 -5
- package/framework/components/chui_graphs/graphs.js +376 -239
- package/framework/components/chui_graphs/styles.css +27 -6
- package/framework/components/chui_hero/hero.js +98 -37
- package/framework/components/chui_hero/styles.css +176 -7
- package/framework/components/chui_html_block/html_block.js +8 -8
- package/framework/components/chui_html_block/styles.css +3 -3
- package/framework/components/chui_hx/hx.js +3 -3
- package/framework/components/chui_hx/styles.css +13 -6
- package/framework/components/chui_icons/icons.js +2115 -2115
- package/framework/components/chui_icons/styles.css +4 -3
- package/framework/components/chui_inputs/chui_check_box/check_box.js +31 -19
- package/framework/components/chui_inputs/chui_check_box/styles.css +30 -21
- package/framework/components/chui_inputs/chui_chips/chips.js +141 -70
- package/framework/components/chui_inputs/chui_chips/styles.css +32 -7
- package/framework/components/chui_inputs/chui_color_picker/color_picker.js +55 -38
- package/framework/components/chui_inputs/chui_color_picker/styles.css +7 -7
- package/framework/components/chui_inputs/chui_combo_box/combo_box.js +127 -109
- package/framework/components/chui_inputs/chui_combo_box/styles.css +23 -21
- package/framework/components/chui_inputs/chui_date/date.js +161 -127
- package/framework/components/chui_inputs/chui_date/styles.css +20 -19
- package/framework/components/chui_inputs/chui_date_range/date_range.js +61 -50
- package/framework/components/chui_inputs/chui_date_range/styles.css +3 -3
- package/framework/components/chui_inputs/chui_datetime/datetime.js +47 -39
- package/framework/components/chui_inputs/chui_datetime/styles.css +3 -3
- package/framework/components/chui_inputs/chui_email/email.js +48 -36
- package/framework/components/chui_inputs/chui_email/styles.css +11 -11
- package/framework/components/chui_inputs/chui_file/file.js +71 -44
- package/framework/components/chui_inputs/chui_file/styles.css +23 -19
- package/framework/components/chui_inputs/chui_hotkey/hotkey.js +101 -76
- package/framework/components/chui_inputs/chui_hotkey/styles.css +6 -6
- package/framework/components/chui_inputs/chui_masked/masked.js +83 -72
- package/framework/components/chui_inputs/chui_masked/styles.css +5 -5
- package/framework/components/chui_inputs/chui_mention/mention.js +87 -40
- package/framework/components/chui_inputs/chui_mention/styles.css +14 -8
- package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +242 -212
- package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +23 -15
- package/framework/components/chui_inputs/chui_number/number.js +84 -70
- package/framework/components/chui_inputs/chui_number/styles.css +13 -13
- package/framework/components/chui_inputs/chui_otp/otp.js +71 -62
- package/framework/components/chui_inputs/chui_otp/styles.css +5 -5
- package/framework/components/chui_inputs/chui_password/password.js +72 -56
- package/framework/components/chui_inputs/chui_password/styles.css +15 -15
- package/framework/components/chui_inputs/chui_radio_button/radio_button.js +37 -25
- package/framework/components/chui_inputs/chui_radio_button/styles.css +22 -22
- package/framework/components/chui_inputs/chui_rating/rating.js +54 -50
- package/framework/components/chui_inputs/chui_rating/styles.css +3 -3
- package/framework/components/chui_inputs/chui_select_box/select_box.js +132 -108
- package/framework/components/chui_inputs/chui_select_box/styles.css +21 -21
- package/framework/components/chui_inputs/chui_slider/slider.js +41 -38
- package/framework/components/chui_inputs/chui_slider/styles.css +7 -5
- package/framework/components/chui_inputs/chui_text/styles.css +14 -14
- package/framework/components/chui_inputs/chui_text/text.js +69 -52
- package/framework/components/chui_inputs/chui_text_area/styles.css +14 -14
- package/framework/components/chui_inputs/chui_text_area/text_area.js +59 -36
- package/framework/components/chui_inputs/chui_time/styles.css +18 -20
- package/framework/components/chui_inputs/chui_time/time.js +71 -49
- package/framework/components/chui_inputs/chui_toggle/styles.css +13 -6
- package/framework/components/chui_inputs/chui_toggle/toggle.js +27 -27
- package/framework/components/chui_json_editor/json_editor.js +137 -127
- package/framework/components/chui_json_editor/styles.css +5 -5
- package/framework/components/chui_json_viewer/json_viewer.js +133 -114
- package/framework/components/chui_json_viewer/styles.css +9 -8
- package/framework/components/chui_kanban/kanban.js +78 -60
- package/framework/components/chui_kanban/styles.css +8 -4
- package/framework/components/chui_kbd/kbd.js +12 -10
- package/framework/components/chui_kbd/styles.css +1 -1
- package/framework/components/chui_label/label.js +31 -29
- package/framework/components/chui_label/styles.css +3 -3
- package/framework/components/chui_link/link.js +36 -29
- package/framework/components/chui_link/styles.css +11 -4
- package/framework/components/chui_list/list.js +42 -38
- package/framework/components/chui_list/styles.css +4 -3
- package/framework/components/chui_markdown_editor/markdown_editor.js +125 -109
- package/framework/components/chui_markdown_editor/styles.css +5 -5
- package/framework/components/chui_media/audio.js +457 -364
- package/framework/components/chui_media/audio_styles.css +74 -37
- package/framework/components/chui_media/image.js +99 -64
- package/framework/components/chui_media/image_compare.js +86 -55
- package/framework/components/chui_media/image_compare_styles.css +5 -5
- package/framework/components/chui_media/image_styles.css +4 -4
- package/framework/components/chui_media/video.js +264 -171
- package/framework/components/chui_media/video_styles.css +57 -24
- package/framework/components/chui_menu_bar/menu_bar.js +67 -65
- package/framework/components/chui_menu_bar/styles.css +14 -12
- package/framework/components/chui_message_bar/message_bar.js +551 -0
- package/framework/components/chui_message_bar/styles.css +248 -0
- package/framework/components/chui_modal/modal.js +81 -56
- package/framework/components/chui_modal/styles.css +3 -2
- package/framework/components/chui_notification/notification.js +107 -69
- package/framework/components/chui_notification/notification_download.js +28 -77
- package/framework/components/chui_notification/notification_download_card.js +115 -0
- package/framework/components/chui_notification/notification_download_progress.css +5 -4
- package/framework/components/chui_notification/notification_download_progress.js +73 -105
- package/framework/components/chui_notification/notification_update.js +44 -37
- package/framework/components/chui_notification/status_plate.css +3 -3
- package/framework/components/chui_notification/status_plate.js +2 -2
- package/framework/components/chui_notification/styles.css +6 -1
- package/framework/components/chui_notification/styles_download.css +2 -2
- package/framework/components/chui_notification/styles_update.css +3 -3
- package/framework/components/chui_org_chart/org_chart.js +101 -62
- package/framework/components/chui_org_chart/styles.css +2 -2
- package/framework/components/chui_pagination/pagination.js +65 -30
- package/framework/components/chui_pagination/styles.css +1 -1
- package/framework/components/chui_paragraph/paragraph.js +2 -2
- package/framework/components/chui_paragraph/styles.css +3 -3
- package/framework/components/chui_popover/popover.js +77 -50
- package/framework/components/chui_popover/styles.css +1 -1
- package/framework/components/chui_popups/popups.js +210 -181
- package/framework/components/chui_popups/styles.css +7 -7
- package/framework/components/chui_print_button/print_button.js +48 -33
- package/framework/components/chui_progress_bar/progress_bar.js +49 -19
- package/framework/components/chui_progress_bar/styles.css +6 -6
- package/framework/components/chui_progress_ring/progress_ring.js +32 -30
- package/framework/components/chui_progress_ring/styles.css +1 -1
- package/framework/components/chui_qrcode/qrcode.js +85 -41
- package/framework/components/chui_query_builder/query_builder.js +263 -170
- package/framework/components/chui_query_builder/styles.css +4 -4
- package/framework/components/chui_radio_group/radio_group.js +36 -26
- package/framework/components/chui_radio_group/styles.css +2 -2
- package/framework/components/chui_result/result.js +41 -31
- package/framework/components/chui_result/styles.css +3 -3
- package/framework/components/chui_scheduler/scheduler.js +126 -104
- package/framework/components/chui_scheduler/styles.css +11 -7
- package/framework/components/chui_screen_spinner/screen_spinner.js +167 -0
- package/framework/components/chui_screen_spinner/styles.css +49 -0
- package/framework/components/chui_segmented_control/segmented_control.js +90 -27
- package/framework/components/chui_segmented_control/styles.css +32 -6
- package/framework/components/chui_settings/settings.js +160 -87
- package/framework/components/chui_settings/styles.css +4 -4
- package/framework/components/chui_shortcut_help/shortcut_help.js +82 -61
- package/framework/components/chui_sidebar_nav/sidebar_nav.js +132 -53
- package/framework/components/chui_sidebar_nav/styles.css +9 -3
- package/framework/components/chui_skeleton/skeleton.js +29 -24
- package/framework/components/chui_slideshow/slideshow.js +122 -103
- package/framework/components/chui_slideshow/styles.css +22 -16
- package/framework/components/chui_spinner/spinner.js +17 -17
- package/framework/components/chui_spinner/styles.css +0 -1
- package/framework/components/chui_split_button/split_button.js +53 -30
- package/framework/components/chui_split_button/styles.css +22 -6
- package/framework/components/chui_splitter/splitter.js +46 -39
- package/framework/components/chui_splitter/styles.css +2 -2
- package/framework/components/chui_statistic/statistic.js +111 -84
- package/framework/components/chui_status_bar/status_bar.js +11 -9
- package/framework/components/chui_status_bar/styles.css +2 -2
- package/framework/components/chui_stepper/stepper.js +230 -54
- package/framework/components/chui_stepper/styles.css +79 -14
- package/framework/components/chui_sticky_bar/sticky_bar.js +53 -17
- package/framework/components/chui_sticky_bar/styles.css +11 -7
- package/framework/components/chui_tabs/chui_tabs.js +100 -46
- package/framework/components/chui_tabs/styles.css +43 -15
- package/framework/components/chui_text_editor/styles.css +24 -23
- package/framework/components/chui_text_editor/text_editor.js +103 -79
- package/framework/components/chui_text_editor/text_editor_panel.js +428 -367
- package/framework/components/chui_theme_toggle/theme_toggle.js +46 -25
- package/framework/components/chui_timeline/styles.css +3 -1
- package/framework/components/chui_timeline/timeline.js +14 -12
- package/framework/components/chui_toast_queue/styles.css +11 -11
- package/framework/components/chui_toast_queue/toast_queue.js +82 -73
- package/framework/components/chui_toolbar/styles.css +2 -2
- package/framework/components/chui_toolbar/toolbar.js +20 -13
- package/framework/components/chui_tooltip/styles.css +2 -2
- package/framework/components/chui_tooltip/tooltip.js +40 -27
- package/framework/components/chui_tour/styles.css +12 -7
- package/framework/components/chui_tour/tour.js +132 -98
- package/framework/components/chui_transfer/styles.css +8 -7
- package/framework/components/chui_transfer/transfer.js +143 -123
- package/framework/components/chui_tree_table/styles.css +4 -4
- package/framework/components/chui_tree_table/tree_table.js +88 -74
- package/framework/components/chui_tree_view/styles.css +14 -10
- package/framework/components/chui_tree_view/tree_view.js +298 -253
- package/framework/components/chui_user_bar/styles.css +145 -0
- package/framework/components/chui_user_bar/user_bar.js +402 -0
- package/framework/components/chui_user_list_bar/styles.css +173 -0
- package/framework/components/chui_user_list_bar/user_list_bar.js +485 -0
- package/framework/components/chui_watermark/watermark.js +41 -33
- package/framework/components/chui_webview/styles.css +2 -2
- package/framework/components/chui_webview/webview.js +64 -52
- package/framework/components/chui_write_bar/styles.css +172 -0
- package/framework/components/chui_write_bar/write_bar.js +320 -0
- package/framework/main_window.js +1234 -0
- package/framework/modules/chui_a11y/chui_a11y.js +153 -123
- package/framework/modules/chui_animations/animations.js +105 -43
- package/framework/modules/chui_animations/motion.js +120 -0
- package/framework/modules/chui_animations/styles.css +37 -4
- package/framework/modules/chui_bridge/preload.js +36 -25
- package/framework/modules/chui_functions.js +69 -63
- package/framework/modules/chui_highlight/chui_highlight.js +25 -22
- package/framework/modules/chui_highlight/styles.css +13 -10
- package/framework/modules/chui_i18n/chui_i18n.js +12 -10
- package/framework/modules/chui_i18n/locales/a11y.js +5 -5
- package/framework/modules/chui_i18n/locales/app_layout.js +5 -5
- package/framework/modules/chui_i18n/locales/calendar.js +3 -3
- package/framework/modules/chui_i18n/locales/common.js +3 -3
- package/framework/modules/chui_i18n/locales/data.js +36 -26
- package/framework/modules/chui_i18n/locales/editors.js +40 -13
- package/framework/modules/chui_i18n/locales/feedback.js +65 -3
- package/framework/modules/chui_i18n/locales/forms.js +8 -8
- package/framework/modules/chui_i18n/locales/graphics.js +8 -8
- package/framework/modules/chui_i18n/locales/media.js +4 -4
- package/framework/modules/chui_i18n/locales/navigation.js +12 -8
- package/framework/modules/chui_i18n/locales/validate.js +3 -3
- package/framework/modules/chui_json/chui_json.js +11 -11
- package/framework/modules/chui_layout/chui_layout.js +12 -10
- package/framework/modules/chui_logger/chui_logger.js +47 -28
- package/framework/modules/chui_page/page.js +39 -33
- package/framework/modules/chui_palette/palette.js +61 -0
- package/framework/modules/chui_qr/chui_qr.js +179 -88
- package/framework/modules/chui_scrollbar/chui_scrollbar.js +79 -68
- package/framework/modules/chui_scrollbar/styles.css +4 -2
- package/framework/modules/chui_services/chui_channels.js +27 -13
- package/framework/modules/chui_services/chui_services.js +47 -39
- package/framework/modules/chui_services/desktop.js +108 -101
- package/framework/modules/chui_sortable/chui_sortable.js +33 -28
- package/framework/modules/chui_validate/chui_validate.js +10 -7
- package/framework/tray_bar/chui_menu_items.js +136 -46
- package/index.d.ts +5046 -0
- package/index.js +199 -1254
- package/package.json +81 -68
- package/framework/components/telegram_bot/chui_telegram_bot.js +0 -184
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
const {Animation} = require(
|
|
2
|
-
const {setStyles, markdownToHtml, getTime, getDayKey, optionOr} = require(
|
|
3
|
-
const {LAYOUT_ROLE, requireLayoutNode} = require(
|
|
4
|
-
const {Icon, Icons} = require(
|
|
5
|
-
const {I18n} = require(
|
|
1
|
+
const { Animation } = require("../../modules/chui_animations/animations");
|
|
2
|
+
const { setStyles, markdownToHtml, getTime, getDayKey, optionOr } = require("../../modules/chui_functions");
|
|
3
|
+
const { LAYOUT_ROLE, requireLayoutNode } = require("../../modules/chui_layout/chui_layout");
|
|
4
|
+
const { Icon, Icons } = require("../chui_icons/icons");
|
|
5
|
+
const { I18n } = require("../../modules/chui_i18n/chui_i18n");
|
|
6
6
|
// Плашка значка состояния — общая на всё семейство карточек уведомлений
|
|
7
|
-
const {setStatusPlate} = require("./status_plate");
|
|
7
|
+
const { setStatusPlate } = require("./status_plate");
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* Карточка уведомления в панели: значок состояния, заголовок с отметкой времени, текст,
|
|
@@ -33,51 +33,56 @@ class Notification {
|
|
|
33
33
|
#id = require("randomstring").generate();
|
|
34
34
|
#time = 5000;
|
|
35
35
|
#notification = document.createElement(`notification`);
|
|
36
|
-
#
|
|
37
|
-
#
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
#
|
|
43
|
-
#
|
|
36
|
+
#notificationIcon = document.createElement("notification_icon");
|
|
37
|
+
#notificationContent = document.createElement("notification_content");
|
|
38
|
+
#notificationHeader = document.createElement("notification_header");
|
|
39
|
+
#notificationTitle = document.createElement("notification_title");
|
|
40
|
+
#notificationDate = document.createElement("notification_date");
|
|
41
|
+
#notificationText = document.createElement("notification_text");
|
|
42
|
+
#notificationProgress = document.createElement("notification_progress");
|
|
43
|
+
#notificationClose = document.createElement("button");
|
|
44
44
|
// Отсчёт автоскрытия: таймер, дедлайн и остаток — чтобы пауза не теряла время
|
|
45
45
|
#timer = undefined;
|
|
46
46
|
#deadline = 0;
|
|
47
47
|
#remaining = 0;
|
|
48
48
|
#dismissed = false;
|
|
49
49
|
|
|
50
|
-
constructor(
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
constructor(
|
|
51
|
+
options = {
|
|
52
|
+
title: String(),
|
|
53
|
+
markdownTitle: String(),
|
|
54
|
+
text: String(),
|
|
55
|
+
markdownText: String(),
|
|
56
|
+
style: undefined,
|
|
57
|
+
showTime: Number(),
|
|
58
|
+
}
|
|
59
|
+
) {
|
|
60
|
+
setStyles(__dirname + "/styles.css", "chUiJS_Notification");
|
|
56
61
|
// Время показа — только настоящее число: заготовка `Number()` из описания опций
|
|
57
62
|
// раньше доезжала как значение и карточка без опций исчезала мгновенно
|
|
58
|
-
const
|
|
59
|
-
if (Number.isFinite(
|
|
63
|
+
const showTime = Number(options.showTime);
|
|
64
|
+
if (Number.isFinite(showTime)) this.#time = showTime;
|
|
60
65
|
this.#notification.id = this.#id;
|
|
61
66
|
// Пустая заготовка опции равносильна отсутствующей: иначе обе опции читались как заданные
|
|
62
67
|
const title = optionOr(options.title, undefined);
|
|
63
|
-
const
|
|
68
|
+
const markdownTitle = optionOr(options.markdownTitle, undefined);
|
|
64
69
|
const text = optionOr(options.text, undefined);
|
|
65
|
-
const
|
|
70
|
+
const markdownText = optionOr(options.markdownText, undefined);
|
|
66
71
|
// Стили заголовка уведомления
|
|
67
|
-
if (title !== undefined &&
|
|
72
|
+
if (title !== undefined && markdownTitle !== undefined) {
|
|
68
73
|
throw new Error("Должна быть установлена одна опция title или markdownTitle");
|
|
69
74
|
} else {
|
|
70
|
-
if (title !== undefined) this.#
|
|
71
|
-
if (
|
|
75
|
+
if (title !== undefined) this.#notificationTitle.innerText = title;
|
|
76
|
+
if (markdownTitle !== undefined) this.#notificationTitle.innerHTML = markdownToHtml(markdownTitle);
|
|
72
77
|
}
|
|
73
78
|
// Стили текста уведомления
|
|
74
|
-
if (text !== undefined &&
|
|
79
|
+
if (text !== undefined && markdownText !== undefined) {
|
|
75
80
|
throw new Error("Должна быть установлена одна опция text или markdownText");
|
|
76
81
|
} else {
|
|
77
|
-
if (text !== undefined) this.#
|
|
78
|
-
if (
|
|
82
|
+
if (text !== undefined) this.#notificationText.innerText = text;
|
|
83
|
+
if (markdownText !== undefined) this.#notificationText.innerHTML = markdownToHtml(markdownText);
|
|
79
84
|
}
|
|
80
|
-
this.#
|
|
85
|
+
this.#notificationDate.innerHTML = getTime();
|
|
81
86
|
// Ключ дня для группировки истории в ящике: подпись группы («Сегодня», «Вчера»,
|
|
82
87
|
// дата) считает ящик, карточке достаточно самого ключа. Записи приходят
|
|
83
88
|
// непрочитанными — ящик снимает отметку, когда его открыли.
|
|
@@ -86,31 +91,37 @@ class Notification {
|
|
|
86
91
|
//
|
|
87
92
|
const style = optionOr(options.style, undefined);
|
|
88
93
|
if (style !== undefined) this.#notification.classList.add(style);
|
|
94
|
+
// Карточка появляется сама, без фокуса, поэтому о ней сообщает роль: ошибку
|
|
95
|
+
// объявляем сразу, остальное — вежливо (то же правило, что у `Toast`)
|
|
96
|
+
this.#notification.setAttribute("role", style === Notification.STYLE.ERROR ? "alert" : "status");
|
|
89
97
|
// Иконка состояния — украшение: стиль читается и по тексту уведомления.
|
|
90
98
|
// Цвет и глиф плашки выбирает общий помощник семейства — по ключу стиля
|
|
91
|
-
this.#
|
|
92
|
-
setStatusPlate(
|
|
99
|
+
this.#notificationIcon.setAttribute("aria-hidden", "true");
|
|
100
|
+
setStatusPlate(
|
|
101
|
+
this.#notificationIcon,
|
|
102
|
+
typeof style === "string" ? style.replace("notification_", "") : undefined
|
|
103
|
+
);
|
|
93
104
|
// Закрытие — настоящая кнопка: доступна мышью, с клавиатуры и скринридеру
|
|
94
|
-
this.#
|
|
95
|
-
this.#
|
|
96
|
-
this.#
|
|
97
|
-
this.#
|
|
98
|
-
this.#
|
|
105
|
+
this.#notificationClose.className = "notification_close";
|
|
106
|
+
this.#notificationClose.type = "button";
|
|
107
|
+
this.#notificationClose.setAttribute("aria-label", I18n.t("a11y.closeNotification"));
|
|
108
|
+
this.#notificationClose.setAttribute("title", I18n.t("common.close"));
|
|
109
|
+
this.#notificationClose.innerHTML = new Icon(Icons.NAVIGATION.CLOSE, "16px").getHTML();
|
|
99
110
|
//
|
|
100
|
-
this.#
|
|
101
|
-
this.#
|
|
111
|
+
this.#notificationHeader.appendChild(this.#notificationTitle);
|
|
112
|
+
this.#notificationHeader.appendChild(this.#notificationDate);
|
|
102
113
|
//
|
|
103
|
-
this.#
|
|
104
|
-
this.#
|
|
105
|
-
this.#notification.appendChild(this.#
|
|
106
|
-
this.#notification.appendChild(this.#
|
|
107
|
-
this.#notification.appendChild(this.#
|
|
114
|
+
this.#notificationContent.appendChild(this.#notificationHeader);
|
|
115
|
+
this.#notificationContent.appendChild(this.#notificationText);
|
|
116
|
+
this.#notification.appendChild(this.#notificationIcon);
|
|
117
|
+
this.#notification.appendChild(this.#notificationContent);
|
|
118
|
+
this.#notification.appendChild(this.#notificationClose);
|
|
108
119
|
// Полоса отсчёта нужна только тем уведомлениям, которые закрываются сами
|
|
109
120
|
if (this.#time > 0) {
|
|
110
|
-
this.#
|
|
121
|
+
this.#notificationProgress.style.animationDuration = `${this.#time}ms`;
|
|
111
122
|
// Отсчёт стартует вместе с таймером, а не с появлением узла в DOM
|
|
112
|
-
this.#
|
|
113
|
-
this.#notification.appendChild(this.#
|
|
123
|
+
this.#notificationProgress.style.animationPlayState = "paused";
|
|
124
|
+
this.#notification.appendChild(this.#notificationProgress);
|
|
114
125
|
}
|
|
115
126
|
// Курсор или фокус внутри карточки останавливают отсчёт
|
|
116
127
|
this.#notification.addEventListener("mouseenter", () => this.pause());
|
|
@@ -128,12 +139,17 @@ class Notification {
|
|
|
128
139
|
panel.appendChild(this.#notification);
|
|
129
140
|
new Animation(this.#notification).slideRightIn();
|
|
130
141
|
// animationend прилетает и от детей (полоса отсчёта) — отсчёт запускаем только по своему
|
|
131
|
-
this.#notification.addEventListener(
|
|
142
|
+
this.#notification.addEventListener("animationend", (event) => {
|
|
132
143
|
if (event.target !== this.#notification) return;
|
|
133
144
|
this.#start(this.#time);
|
|
134
145
|
});
|
|
135
146
|
this.#notification.addEventListener("click", () => this.dismiss());
|
|
136
|
-
if (showOnSystem)
|
|
147
|
+
if (showOnSystem)
|
|
148
|
+
require("electron").ipcRenderer.send(
|
|
149
|
+
"show_system_notification",
|
|
150
|
+
this.#notificationTitle.innerText,
|
|
151
|
+
this.#notificationText.innerText
|
|
152
|
+
);
|
|
137
153
|
return this;
|
|
138
154
|
}
|
|
139
155
|
|
|
@@ -144,7 +160,7 @@ class Notification {
|
|
|
144
160
|
clearTimeout(this.#timer);
|
|
145
161
|
this.#timer = undefined;
|
|
146
162
|
this.#remaining = Math.max(0, this.#deadline - Date.now());
|
|
147
|
-
this.#
|
|
163
|
+
this.#notificationProgress.style.animationPlayState = "paused";
|
|
148
164
|
return this;
|
|
149
165
|
}
|
|
150
166
|
|
|
@@ -166,7 +182,7 @@ class Notification {
|
|
|
166
182
|
this.#dismissed = true;
|
|
167
183
|
this.#clearTimer();
|
|
168
184
|
// Полоса отсчёта больше не нужна: её animationend мог бы прилететь во время ухода
|
|
169
|
-
this.#
|
|
185
|
+
this.#notificationProgress.remove();
|
|
170
186
|
this.#removeNotification(this.#notification);
|
|
171
187
|
return this;
|
|
172
188
|
}
|
|
@@ -176,7 +192,7 @@ class Notification {
|
|
|
176
192
|
this.#remaining = duration;
|
|
177
193
|
this.#deadline = Date.now() + duration;
|
|
178
194
|
this.#timer = setTimeout(() => this.dismiss(), duration);
|
|
179
|
-
this.#
|
|
195
|
+
this.#notificationProgress.style.animationPlayState = "running";
|
|
180
196
|
return this;
|
|
181
197
|
}
|
|
182
198
|
|
|
@@ -188,32 +204,54 @@ class Notification {
|
|
|
188
204
|
|
|
189
205
|
#removeNotification(notification) {
|
|
190
206
|
// Анимация ухода требует уже заданного animationName — у невидимого уведомления его нет
|
|
191
|
-
if (notification.style.animationName === "")
|
|
207
|
+
if (notification.style.animationName === "") {
|
|
208
|
+
notification.style.animationName = "slide-right-in";
|
|
209
|
+
notification.dataset.motion = "enter";
|
|
210
|
+
}
|
|
192
211
|
new Animation(notification).slideRightOutAndRemove();
|
|
193
|
-
|
|
212
|
+
// Въезд в ящик — событие одноразовое: сняв себя после своего кадра, обработчик больше
|
|
213
|
+
// не трогает карточку. Без снятия его ловил любой конец кадра — включая кадр уборки:
|
|
214
|
+
// запись переселялась в начало списка и кадр начинался заново
|
|
215
|
+
const land = (event) => {
|
|
194
216
|
if (event.target !== notification) return;
|
|
195
|
-
|
|
196
|
-
//
|
|
217
|
+
notification.removeEventListener("animationend", land);
|
|
218
|
+
// Следы кадра ухода снимаем точечно: `removeAttribute("style")` снёс бы и чужие
|
|
219
|
+
// инлайновые значения (в карточке их несколько — отсчёт, отклик на наведение).
|
|
220
|
+
// Вид ухода держит конечное состояние (`fill-mode: both`), а инлайновое имя кадра
|
|
221
|
+
// перебило бы любой следующий: без этого въезд записи не проигрался бы
|
|
197
222
|
notification.style.removeProperty("animation-name");
|
|
223
|
+
notification.removeAttribute("data-motion");
|
|
198
224
|
notification.style.removeProperty("transition");
|
|
199
|
-
notification.style.display = 'flex';
|
|
200
|
-
notification.style.width = '-webkit-fill-available';
|
|
201
|
-
notification.style.opacity = "0"
|
|
202
|
-
notification.style.transform = "translateX(100%)"
|
|
203
225
|
// В ящике карточка — запись истории: полоса отсчёта и закрытие там лишние
|
|
204
226
|
notification.classList.add("notification_in_box");
|
|
205
227
|
const box = requireLayoutNode(LAYOUT_ROLE.NOTIFICATION_BOX_MAIN, notification);
|
|
206
228
|
// Новые записи идут сверху: история читается от свежего к старому, и группы дней
|
|
207
229
|
// (их расставляет NotificationBox) ложатся в том же порядке — «Сегодня» первой.
|
|
208
|
-
box.prepend(notification)
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
230
|
+
box.prepend(notification);
|
|
231
|
+
/*
|
|
232
|
+
* Запись встаёт на место тем же кадром, каким пришёл тост: она только что уехала вправо,
|
|
233
|
+
* поэтому и возвращается оттуда. Прежде карточка ставилась инлайновыми `opacity`
|
|
234
|
+
* и `transform` и ждала 500 мс — и слайд не проигрывался вовсе: вид `exit` держит
|
|
235
|
+
* `transform` вне переходов (`[data-motion]`), поэтому запись просто вспыхивала
|
|
236
|
+
* на месте. Кадр ведёт драйвер: время и кривую берёт вид `enter` из токенов темы.
|
|
237
|
+
*/
|
|
238
|
+
new Animation(notification).slideRightIn();
|
|
239
|
+
// Кадр въезда доигран — запись возвращается к стилям: инлайнового имени кадра
|
|
240
|
+
// и вида у неё не остаётся, иначе они спорили бы со следующим кадром (уборкой)
|
|
241
|
+
notification.addEventListener(
|
|
242
|
+
"animationend",
|
|
243
|
+
(event) => {
|
|
244
|
+
if (event.target !== notification) return;
|
|
245
|
+
notification.style.removeProperty("animation-name");
|
|
246
|
+
notification.removeAttribute("data-motion");
|
|
247
|
+
},
|
|
248
|
+
{ once: true }
|
|
249
|
+
);
|
|
250
|
+
};
|
|
251
|
+
notification.addEventListener("animationend", land);
|
|
214
252
|
}
|
|
215
253
|
|
|
216
|
-
static STYLE = { ERROR:
|
|
254
|
+
static STYLE = { ERROR: "notification_error", SUCCESS: "notification_success", WARNING: "notification_warning" };
|
|
217
255
|
}
|
|
218
256
|
|
|
219
|
-
exports.Notification = Notification
|
|
257
|
+
exports.Notification = Notification;
|
|
@@ -1,92 +1,43 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const {
|
|
3
|
-
|
|
4
|
-
const {
|
|
5
|
-
// Плашка значка — общая на всё семейство карточек уведомлений
|
|
6
|
-
const {createStatusPlate, setStatusPlate} = require("./status_plate");
|
|
1
|
+
const { optionOr } = require("../../modules/chui_functions");
|
|
2
|
+
const { Icons } = require("../chui_icons/icons");
|
|
3
|
+
// Каркас карточки загрузки — общий с `DownloadProgressNotification` (см. модуль)
|
|
4
|
+
const { createDownloadCard, showDownloadCard, finishDownloadCard } = require("./notification_download_card");
|
|
7
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Уведомление о загрузке файла: название, текст хода и итог (`done`/`error`).
|
|
8
|
+
*
|
|
9
|
+
* Тело — одна строка текста, поэтому в общий каркас она не входит: у карточки с прогрессом
|
|
10
|
+
* тело другое (дорожка и счётчик), и общим остаётся только каркас с шапкой и статусом.
|
|
11
|
+
*/
|
|
8
12
|
class DownloadNotification {
|
|
9
|
-
#
|
|
10
|
-
#
|
|
11
|
-
#download_notification_icon = undefined;
|
|
12
|
-
#download_notification_content = document.createElement("download_notification_content");
|
|
13
|
-
#download_notification_header = document.createElement("download_notification_header");
|
|
14
|
-
#download_notification_title = document.createElement("download_notification_title");
|
|
15
|
-
#download_notification_date = document.createElement("download_notification_date");
|
|
16
|
-
#download_notification_body = document.createElement("download_notification_body");
|
|
17
|
-
#download_notification_text = document.createElement("download_notification_text");
|
|
13
|
+
#card;
|
|
14
|
+
#text = document.createElement("download_notification_text");
|
|
18
15
|
constructor(options = { title: String(), text: String(), type: String() }) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
this.#card = createDownloadCard({
|
|
17
|
+
tag: "download_notification",
|
|
18
|
+
styles: { file: "styles_download.css", id: "chUiJS_downloadNotification" },
|
|
19
|
+
glyph: Icons.FILE.DOWNLOAD_FOR_OFFLINE,
|
|
20
|
+
title: options.title,
|
|
21
|
+
});
|
|
22
|
+
// Пустая заготовка опции равносильна отсутствующей: текст хода обязателен
|
|
23
23
|
const text = optionOr(options.text, undefined);
|
|
24
|
-
if (
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
throw new Error("Должна быть установлена опция title");
|
|
28
|
-
}
|
|
29
|
-
this.#download_notification_body.style.width = "-webkit-fill-available"
|
|
30
|
-
this.#download_notification_date.innerHTML = getTime();
|
|
31
|
-
if (text !== undefined) {
|
|
32
|
-
this.#download_notification_text.innerText = text;
|
|
33
|
-
} else {
|
|
34
|
-
throw new Error("Должна быть установлена опция text");
|
|
35
|
-
}
|
|
36
|
-
this.#download_notification_header.appendChild(this.#download_notification_title)
|
|
37
|
-
this.#download_notification_header.appendChild(this.#download_notification_date)
|
|
38
|
-
this.#download_notification_content.appendChild(this.#download_notification_header)
|
|
39
|
-
this.#download_notification_body.appendChild(this.#download_notification_text)
|
|
40
|
-
this.#download_notification_content.appendChild(this.#download_notification_body)
|
|
41
|
-
// Значок состояния — в плашке слева, как у Notification
|
|
42
|
-
this.#download_notification_icon = createStatusPlate(undefined, Icons.FILE.DOWNLOAD_FOR_OFFLINE);
|
|
43
|
-
this.#download_notification.appendChild(this.#download_notification_icon)
|
|
44
|
-
this.#download_notification.appendChild(this.#download_notification_content)
|
|
24
|
+
if (text === undefined) throw new Error("Должна быть установлена опция text");
|
|
25
|
+
this.#text.innerText = text;
|
|
26
|
+
this.#card.body.appendChild(this.#text);
|
|
45
27
|
}
|
|
46
28
|
update(title = String(), text = String()) {
|
|
47
|
-
this.#
|
|
48
|
-
this.#
|
|
29
|
+
this.#card.title.innerText = title;
|
|
30
|
+
this.#text.innerText = text;
|
|
49
31
|
}
|
|
50
32
|
show() {
|
|
51
|
-
|
|
52
|
-
const panel = requireLayoutNode(LAYOUT_ROLE.NOTIFICATION_PANEL, this.#download_notification);
|
|
53
|
-
panel.appendChild(this.#download_notification);
|
|
54
|
-
new Animation(this.#download_notification).slideRightIn();
|
|
55
|
-
this.#download_notification.addEventListener("click", () => this.#hideNotification(this.#download_notification));
|
|
33
|
+
showDownloadCard(this.#card);
|
|
56
34
|
}
|
|
57
35
|
done() {
|
|
58
|
-
this.#
|
|
36
|
+
finishDownloadCard(this.#card, "success");
|
|
59
37
|
}
|
|
60
38
|
error() {
|
|
61
|
-
this.#
|
|
62
|
-
}
|
|
63
|
-
/** Итог загрузки: цвет статуса несут класс карточки и плашка значка */
|
|
64
|
-
#renderTest(className, status) {
|
|
65
|
-
const notification = this.#download_notification;
|
|
66
|
-
notification.className = className;
|
|
67
|
-
setStatusPlate(this.#download_notification_icon, status);
|
|
68
|
-
setTimeout(() => this.#hideNotification(notification), 2000);
|
|
69
|
-
}
|
|
70
|
-
#hideNotification(notification) {
|
|
71
|
-
new Animation(notification).slideRightOutAndRemove();
|
|
72
|
-
notification.addEventListener("animationend", () => {
|
|
73
|
-
// Точечный сброс следов анимации вместо стирания всего атрибута `style`
|
|
74
|
-
notification.style.removeProperty("animation-name");
|
|
75
|
-
notification.style.removeProperty("transition");
|
|
76
|
-
notification.style.display = 'flex';
|
|
77
|
-
notification.style.width = '-webkit-fill-available';
|
|
78
|
-
notification.style.opacity = "0"
|
|
79
|
-
notification.style.transform = "translateX(100%)"
|
|
80
|
-
let box = requireLayoutNode(LAYOUT_ROLE.NOTIFICATION_BOX_MAIN, notification);
|
|
81
|
-
// В истории запись плоская и без курсора: класс снимает стекло, тень и отклик на наведение
|
|
82
|
-
notification.classList.add("notification_in_box");
|
|
83
|
-
box.appendChild(notification)
|
|
84
|
-
setTimeout(() => {
|
|
85
|
-
notification.style.opacity = "1"
|
|
86
|
-
notification.style.transform = "translateX(0)"
|
|
87
|
-
}, 500)
|
|
88
|
-
})
|
|
39
|
+
finishDownloadCard(this.#card, "error");
|
|
89
40
|
}
|
|
90
41
|
}
|
|
91
42
|
|
|
92
|
-
exports.DownloadNotification = DownloadNotification
|
|
43
|
+
exports.DownloadNotification = DownloadNotification;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
const { Animation } = require("../../modules/chui_animations/animations");
|
|
2
|
+
const { setStyles, getTime, optionOr } = require("../../modules/chui_functions");
|
|
3
|
+
const { LAYOUT_ROLE, requireLayoutNode } = require("../../modules/chui_layout/chui_layout");
|
|
4
|
+
// Плашка значка — общая на всё семейство карточек уведомлений
|
|
5
|
+
const { createStatusPlate, setStatusPlate } = require("./status_plate");
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Каркас карточки загрузки: шапка, плашка значка и жизненный цикл (`show`, `done`, `error`,
|
|
9
|
+
* уход в историю). Одно решение на две карточки — `DownloadNotification` и
|
|
10
|
+
* `DownloadProgressNotification`: тела у них разные (строка текста против дорожки прогресса)
|
|
11
|
+
* и таблицы стилей свои, а шапка с датой, статус и поведение совпадают.
|
|
12
|
+
*
|
|
13
|
+
* Прежде это были две почти дословные копии (`diff` находил только имя экспорта), из-за чего
|
|
14
|
+
* правка в одной не доходила до второй: `update(title, text)` и `update(title, text, value, max)`
|
|
15
|
+
* разошлись, а статус с уходом в историю пришлось бы править дважды.
|
|
16
|
+
*
|
|
17
|
+
* Карточка — обычный объект с узлами, а не класс с наследованием: приватные поля базового
|
|
18
|
+
* класса наследнику не видны, и ради узлов, которые компонент всё равно строит сам, пришлось бы
|
|
19
|
+
* открывать наружу геттеры. По той же причине рядом живёт модуль плашки (`status_plate.js`).
|
|
20
|
+
*/
|
|
21
|
+
function createDownloadCard(options = { tag: String(), styles: Object(), glyph: undefined, title: String() }) {
|
|
22
|
+
setStyles(__dirname + "/" + options.styles.file, options.styles.id);
|
|
23
|
+
// Пустая заготовка опции равносильна отсутствующей: карточка без названия не собирается
|
|
24
|
+
const title = optionOr(options.title, undefined);
|
|
25
|
+
if (title === undefined) throw new Error("Должна быть установлена опция title");
|
|
26
|
+
|
|
27
|
+
const root = document.createElement(options.tag);
|
|
28
|
+
root.id = require("randomstring").generate();
|
|
29
|
+
// Ход загрузки объявляется вежливо; итог с ошибкой меняет роль в `finishDownloadCard()`
|
|
30
|
+
root.setAttribute("role", "status");
|
|
31
|
+
|
|
32
|
+
const content = document.createElement("download_notification_content");
|
|
33
|
+
const header = document.createElement("download_notification_header");
|
|
34
|
+
const titleNode = document.createElement("download_notification_title");
|
|
35
|
+
const body = document.createElement("download_notification_body");
|
|
36
|
+
titleNode.innerText = title;
|
|
37
|
+
body.style.width = "-webkit-fill-available";
|
|
38
|
+
header.appendChild(titleNode);
|
|
39
|
+
header.appendChild(createDateNode());
|
|
40
|
+
content.appendChild(header);
|
|
41
|
+
content.appendChild(body);
|
|
42
|
+
// Значок состояния — в плашке слева, как у Notification
|
|
43
|
+
const plate = createStatusPlate(undefined, options.glyph);
|
|
44
|
+
root.appendChild(plate);
|
|
45
|
+
root.appendChild(content);
|
|
46
|
+
return { root, body, title: titleNode, plate };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/** Дата карточки в истории: время постановки в очередь загрузок */
|
|
50
|
+
function createDateNode() {
|
|
51
|
+
const date = document.createElement("download_notification_date");
|
|
52
|
+
date.innerHTML = getTime();
|
|
53
|
+
return date;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** Показать карточку в панели уведомлений; клик по карточке убирает её */
|
|
57
|
+
function showDownloadCard(card = Object()) {
|
|
58
|
+
// Панель и ящик — части layout'а: у каждого окна свои
|
|
59
|
+
const panel = requireLayoutNode(LAYOUT_ROLE.NOTIFICATION_PANEL, card.root);
|
|
60
|
+
panel.appendChild(card.root);
|
|
61
|
+
new Animation(card.root).slideRightIn();
|
|
62
|
+
card.root.addEventListener("click", () => hideDownloadCard(card.root));
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Итог загрузки: цвет статуса несут класс карточки и плашка значка. Класс собирается из статуса
|
|
67
|
+
* (`download_notification_success` / `download_notification_error`) — прежде он приходил
|
|
68
|
+
* отдельным первым аргументом, хотя всегда был его же производной.
|
|
69
|
+
*/
|
|
70
|
+
function finishDownloadCard(card = Object(), status = String()) {
|
|
71
|
+
const notification = card.root;
|
|
72
|
+
notification.className = `download_notification_${status}`;
|
|
73
|
+
// Ошибку объявляем сразу, успех — вежливо (как у `Toast`)
|
|
74
|
+
notification.setAttribute("role", status === "error" ? "alert" : "status");
|
|
75
|
+
setStatusPlate(card.plate, status);
|
|
76
|
+
setTimeout(() => hideDownloadCard(notification), 2000);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Убрать карточку: она уезжает в ящик уведомлений плоской записью истории */
|
|
80
|
+
function hideDownloadCard(notification = undefined) {
|
|
81
|
+
new Animation(notification).slideRightOutAndRemove();
|
|
82
|
+
// Въезд в ящик — событие одноразовое: сняв себя после своего кадра, обработчик не трогает
|
|
83
|
+
// карточку дальше. Иначе он ловил бы любой конец кадра — включая кадр уборки — и переселял бы
|
|
84
|
+
// запись в начало списка, начиная её кадр заново
|
|
85
|
+
const land = (event) => {
|
|
86
|
+
if (event.target !== notification) return;
|
|
87
|
+
notification.removeEventListener("animationend", land);
|
|
88
|
+
// Точечный сброс следов анимации вместо стирания всего атрибута `style`:
|
|
89
|
+
// вид ухода держит конечное состояние, а инлайновое имя кадра перебило бы следующий
|
|
90
|
+
notification.style.removeProperty("animation-name");
|
|
91
|
+
notification.removeAttribute("data-motion");
|
|
92
|
+
notification.style.removeProperty("transition");
|
|
93
|
+
const box = requireLayoutNode(LAYOUT_ROLE.NOTIFICATION_BOX_MAIN, notification);
|
|
94
|
+
// В истории запись плоская и без курсора: класс снимает стекло, тень и отклик на наведение
|
|
95
|
+
notification.classList.add("notification_in_box");
|
|
96
|
+
box.appendChild(notification);
|
|
97
|
+
// Запись встаёт на место кадром прихода — тем же, каким въехала в панель
|
|
98
|
+
new Animation(notification).slideRightIn();
|
|
99
|
+
notification.addEventListener(
|
|
100
|
+
"animationend",
|
|
101
|
+
(event) => {
|
|
102
|
+
if (event.target !== notification) return;
|
|
103
|
+
notification.style.removeProperty("animation-name");
|
|
104
|
+
notification.removeAttribute("data-motion");
|
|
105
|
+
},
|
|
106
|
+
{ once: true }
|
|
107
|
+
);
|
|
108
|
+
};
|
|
109
|
+
notification.addEventListener("animationend", land);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
exports.createDownloadCard = createDownloadCard;
|
|
113
|
+
exports.showDownloadCard = showDownloadCard;
|
|
114
|
+
exports.finishDownloadCard = finishDownloadCard;
|
|
115
|
+
exports.hideDownloadCard = hideDownloadCard;
|
|
@@ -8,7 +8,7 @@ notification_download_progress {
|
|
|
8
8
|
box-sizing: border-box;
|
|
9
9
|
/* Тот же материал и ритм, что у карточки Notification */
|
|
10
10
|
border-radius: var(--radius_md);
|
|
11
|
-
margin: var(--
|
|
11
|
+
margin: var(--block_margin);
|
|
12
12
|
font-size: var(--font_default_size);
|
|
13
13
|
padding: 12px 14px;
|
|
14
14
|
background: var(--header_background);
|
|
@@ -108,7 +108,8 @@ download_progress_text_block {
|
|
|
108
108
|
margin: 0 0 4px;
|
|
109
109
|
}
|
|
110
110
|
|
|
111
|
-
download_progress_text,
|
|
111
|
+
download_progress_text,
|
|
112
|
+
download_progress_count {
|
|
112
113
|
font-size: var(--font_notification_size);
|
|
113
114
|
}
|
|
114
115
|
|
|
@@ -129,7 +130,7 @@ download_progress_count {
|
|
|
129
130
|
}
|
|
130
131
|
|
|
131
132
|
.download_progress_bar::-webkit-progress-bar {
|
|
132
|
-
background: var(--
|
|
133
|
+
background: var(--player_background);
|
|
133
134
|
border-radius: var(--radius_pill);
|
|
134
135
|
border: none;
|
|
135
136
|
}
|
|
@@ -137,4 +138,4 @@ download_progress_count {
|
|
|
137
138
|
.download_progress_bar::-webkit-progress-value {
|
|
138
139
|
background: var(--blue_prime_background);
|
|
139
140
|
border-radius: var(--radius_pill);
|
|
140
|
-
}
|
|
141
|
+
}
|