chuijs 4.0.3 → 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 +536 -0
- package/framework/appLayout/default/chui_app_layout.js +361 -303
- package/framework/appLayout/default/global_style.css +243 -89
- package/framework/appLayout/default/main_theme_style.css +188 -101
- package/framework/components/chui_accordion/accordion.js +17 -17
- package/framework/components/chui_accordion/styles.css +7 -7
- package/framework/components/chui_action_sheet/action_sheet.js +35 -32
- package/framework/components/chui_action_sheet/styles.css +10 -4
- 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 +4 -4
- package/framework/components/chui_affix/styles.css +5 -0
- package/framework/components/chui_alert/alert.js +11 -5
- package/framework/components/chui_alert/styles.css +7 -0
- package/framework/components/chui_avatar/avatar.js +13 -13
- package/framework/components/chui_avatar/styles.css +1 -1
- package/framework/components/chui_avatar_group/avatar_group.js +4 -4
- package/framework/components/chui_avatar_group/styles.css +1 -1
- package/framework/components/chui_backtop/backtop.js +25 -2
- package/framework/components/chui_backtop/styles.css +21 -0
- package/framework/components/chui_badge/badge.js +15 -15
- 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/styles.css +1 -1
- package/framework/components/chui_button/button.js +24 -28
- package/framework/components/chui_button/styles.css +5 -5
- package/framework/components/chui_calendar/calendar.js +6 -6
- package/framework/components/chui_card/card.js +14 -14
- 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 +73 -51
- package/framework/components/chui_chat/styles.css +18 -7
- package/framework/components/chui_clipboard_history/clipboard_history.js +25 -20
- package/framework/components/chui_clipboard_history/styles.css +10 -8
- package/framework/components/chui_code/code.js +8 -8
- package/framework/components/chui_code/styles.css +2 -2
- package/framework/components/chui_code_editor/code_editor.js +26 -26
- package/framework/components/chui_code_editor/styles.css +3 -3
- package/framework/components/chui_command_palette/command_palette.js +29 -29
- package/framework/components/chui_command_palette/styles.css +5 -5
- package/framework/components/chui_console/console.js +9 -9
- package/framework/components/chui_console/styles.css +5 -2
- package/framework/components/chui_content_block/content_block.js +2 -2
- package/framework/components/chui_context_menu/context_menu.js +162 -54
- package/framework/components/chui_context_menu/styles.css +82 -8
- package/framework/components/chui_custom_element/custom_element.js +11 -11
- package/framework/components/chui_data_grid/data_grid.js +268 -268
- package/framework/components/chui_data_grid/styles.css +14 -14
- package/framework/components/chui_descriptions/styles.css +1 -1
- package/framework/components/chui_details/details.js +12 -12
- package/framework/components/chui_details/styles.css +7 -7
- package/framework/components/chui_diff_viewer/diff_viewer.js +88 -88
- package/framework/components/chui_diff_viewer/styles.css +9 -9
- package/framework/components/chui_divider/divider.js +6 -6
- package/framework/components/chui_divider/styles.css +2 -2
- package/framework/components/chui_drawer/drawer.js +37 -14
- package/framework/components/chui_drawer/styles.css +18 -4
- package/framework/components/chui_drop_zone/drop_zone.js +6 -6
- package/framework/components/chui_drop_zone/styles.css +10 -6
- package/framework/components/chui_fieldset/fieldset.js +6 -6
- package/framework/components/chui_fieldset/styles.css +5 -5
- package/framework/components/chui_file_explorer/file_explorer.js +115 -115
- package/framework/components/chui_file_explorer/styles.css +6 -6
- package/framework/components/chui_form/form.js +11 -11
- package/framework/components/chui_gantt/gantt.js +41 -41
- package/framework/components/chui_gantt/styles.css +5 -5
- package/framework/components/chui_graphs/graphs.js +82 -46
- package/framework/components/chui_graphs/styles.css +26 -5
- package/framework/components/chui_hero/hero.js +63 -20
- package/framework/components/chui_hero/styles.css +176 -7
- package/framework/components/chui_html_block/html_block.js +5 -5
- package/framework/components/chui_html_block/styles.css +1 -1
- package/framework/components/chui_hx/styles.css +2 -2
- package/framework/components/chui_icons/icons.js +7 -7
- package/framework/components/chui_icons/styles.css +2 -1
- package/framework/components/chui_inputs/chui_check_box/styles.css +12 -3
- package/framework/components/chui_inputs/chui_chips/chips.js +92 -31
- package/framework/components/chui_inputs/chui_chips/styles.css +28 -5
- package/framework/components/chui_inputs/chui_color_picker/color_picker.js +20 -15
- package/framework/components/chui_inputs/chui_color_picker/styles.css +7 -7
- package/framework/components/chui_inputs/chui_combo_box/combo_box.js +58 -58
- package/framework/components/chui_inputs/chui_combo_box/styles.css +9 -9
- package/framework/components/chui_inputs/chui_date/date.js +93 -95
- package/framework/components/chui_inputs/chui_date/styles.css +8 -8
- package/framework/components/chui_inputs/chui_date_range/date_range.js +22 -22
- package/framework/components/chui_inputs/chui_date_range/styles.css +3 -3
- package/framework/components/chui_inputs/chui_datetime/datetime.js +12 -12
- package/framework/components/chui_inputs/chui_datetime/styles.css +3 -3
- package/framework/components/chui_inputs/chui_email/email.js +10 -10
- package/framework/components/chui_inputs/chui_email/styles.css +6 -6
- package/framework/components/chui_inputs/chui_file/file.js +8 -8
- package/framework/components/chui_inputs/chui_file/styles.css +12 -9
- package/framework/components/chui_inputs/chui_hotkey/hotkey.js +39 -39
- package/framework/components/chui_inputs/chui_hotkey/styles.css +6 -6
- package/framework/components/chui_inputs/chui_masked/masked.js +44 -44
- package/framework/components/chui_inputs/chui_masked/styles.css +5 -5
- package/framework/components/chui_inputs/chui_mention/mention.js +13 -13
- package/framework/components/chui_inputs/chui_mention/styles.css +14 -8
- package/framework/components/chui_inputs/chui_multi_combo_box/multi_combo_box.js +147 -137
- package/framework/components/chui_inputs/chui_multi_combo_box/styles.css +14 -8
- package/framework/components/chui_inputs/chui_number/number.js +42 -45
- package/framework/components/chui_inputs/chui_number/styles.css +6 -6
- package/framework/components/chui_inputs/chui_otp/otp.js +32 -32
- package/framework/components/chui_inputs/chui_otp/styles.css +5 -5
- package/framework/components/chui_inputs/chui_password/password.js +30 -36
- package/framework/components/chui_inputs/chui_password/styles.css +7 -7
- package/framework/components/chui_inputs/chui_radio_button/styles.css +2 -2
- package/framework/components/chui_inputs/chui_rating/rating.js +28 -28
- package/framework/components/chui_inputs/chui_rating/styles.css +3 -3
- package/framework/components/chui_inputs/chui_select_box/select_box.js +54 -54
- package/framework/components/chui_inputs/chui_select_box/styles.css +10 -10
- package/framework/components/chui_inputs/chui_slider/slider.js +14 -14
- package/framework/components/chui_inputs/chui_slider/styles.css +5 -4
- package/framework/components/chui_inputs/chui_text/styles.css +7 -7
- package/framework/components/chui_inputs/chui_text/text.js +13 -17
- package/framework/components/chui_inputs/chui_text_area/styles.css +8 -8
- package/framework/components/chui_inputs/chui_text_area/text_area.js +23 -23
- package/framework/components/chui_inputs/chui_time/styles.css +13 -17
- package/framework/components/chui_inputs/chui_time/time.js +35 -24
- package/framework/components/chui_inputs/chui_toggle/styles.css +10 -3
- package/framework/components/chui_inputs/chui_toggle/toggle.js +16 -16
- package/framework/components/chui_json_editor/json_editor.js +87 -87
- package/framework/components/chui_json_editor/styles.css +5 -5
- package/framework/components/chui_json_viewer/json_viewer.js +80 -80
- package/framework/components/chui_json_viewer/styles.css +6 -6
- package/framework/components/chui_kanban/kanban.js +27 -27
- package/framework/components/chui_kanban/styles.css +8 -4
- package/framework/components/chui_kbd/styles.css +1 -1
- package/framework/components/chui_label/label.js +17 -17
- package/framework/components/chui_label/styles.css +1 -1
- package/framework/components/chui_link/link.js +9 -9
- package/framework/components/chui_link/styles.css +11 -4
- package/framework/components/chui_list/list.js +11 -11
- package/framework/components/chui_list/styles.css +2 -2
- package/framework/components/chui_markdown_editor/markdown_editor.js +66 -66
- package/framework/components/chui_markdown_editor/styles.css +5 -5
- package/framework/components/chui_media/audio.js +240 -246
- package/framework/components/chui_media/audio_styles.css +41 -23
- package/framework/components/chui_media/image.js +49 -46
- package/framework/components/chui_media/image_compare.js +35 -35
- package/framework/components/chui_media/image_compare_styles.css +5 -5
- package/framework/components/chui_media/image_styles.css +1 -1
- package/framework/components/chui_media/video.js +148 -148
- package/framework/components/chui_media/video_styles.css +27 -11
- package/framework/components/chui_menu_bar/menu_bar.js +54 -54
- package/framework/components/chui_menu_bar/styles.css +10 -10
- 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 +37 -13
- package/framework/components/chui_notification/notification.js +76 -54
- package/framework/components/chui_notification/notification_download.js +26 -81
- package/framework/components/chui_notification/notification_download_card.js +115 -0
- package/framework/components/chui_notification/notification_download_progress.css +2 -2
- package/framework/components/chui_notification/notification_download_progress.js +70 -108
- package/framework/components/chui_notification/notification_update.js +31 -31
- package/framework/components/chui_notification/status_plate.css +3 -3
- package/framework/components/chui_notification/styles.css +6 -1
- package/framework/components/chui_notification/styles_download.css +1 -1
- package/framework/components/chui_notification/styles_update.css +2 -2
- package/framework/components/chui_org_chart/org_chart.js +29 -29
- package/framework/components/chui_org_chart/styles.css +2 -2
- package/framework/components/chui_pagination/pagination.js +3 -3
- package/framework/components/chui_pagination/styles.css +1 -1
- package/framework/components/chui_paragraph/styles.css +2 -2
- package/framework/components/chui_popover/popover.js +29 -23
- package/framework/components/chui_popover/styles.css +1 -1
- package/framework/components/chui_popups/popups.js +124 -124
- package/framework/components/chui_popups/styles.css +5 -5
- package/framework/components/chui_print_button/print_button.js +15 -10
- package/framework/components/chui_progress_bar/progress_bar.js +34 -12
- package/framework/components/chui_progress_bar/styles.css +4 -4
- package/framework/components/chui_progress_ring/progress_ring.js +15 -15
- package/framework/components/chui_progress_ring/styles.css +1 -1
- package/framework/components/chui_qrcode/qrcode.js +12 -12
- package/framework/components/chui_query_builder/query_builder.js +46 -46
- package/framework/components/chui_query_builder/styles.css +4 -4
- package/framework/components/chui_radio_group/styles.css +1 -1
- package/framework/components/chui_result/result.js +15 -15
- package/framework/components/chui_result/styles.css +3 -3
- package/framework/components/chui_scheduler/scheduler.js +74 -74
- package/framework/components/chui_scheduler/styles.css +5 -5
- 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 +63 -6
- package/framework/components/chui_segmented_control/styles.css +32 -6
- package/framework/components/chui_settings/settings.js +45 -46
- package/framework/components/chui_settings/styles.css +4 -4
- package/framework/components/chui_shortcut_help/shortcut_help.js +32 -34
- package/framework/components/chui_sidebar_nav/sidebar_nav.js +98 -29
- package/framework/components/chui_sidebar_nav/styles.css +9 -3
- package/framework/components/chui_slideshow/slideshow.js +85 -85
- package/framework/components/chui_slideshow/styles.css +6 -6
- package/framework/components/chui_spinner/spinner.js +10 -10
- package/framework/components/chui_split_button/split_button.js +30 -12
- package/framework/components/chui_split_button/styles.css +21 -5
- package/framework/components/chui_splitter/splitter.js +11 -11
- package/framework/components/chui_splitter/styles.css +2 -2
- package/framework/components/chui_statistic/statistic.js +47 -47
- package/framework/components/chui_status_bar/styles.css +2 -2
- package/framework/components/chui_stepper/stepper.js +202 -31
- package/framework/components/chui_stepper/styles.css +79 -14
- package/framework/components/chui_sticky_bar/sticky_bar.js +44 -13
- package/framework/components/chui_sticky_bar/styles.css +10 -8
- package/framework/components/chui_tabs/chui_tabs.js +74 -26
- package/framework/components/chui_tabs/styles.css +40 -12
- package/framework/components/chui_text_editor/styles.css +7 -7
- package/framework/components/chui_text_editor/text_editor.js +56 -56
- package/framework/components/chui_text_editor/text_editor_panel.js +173 -174
- package/framework/components/chui_theme_toggle/theme_toggle.js +21 -5
- package/framework/components/chui_timeline/styles.css +3 -1
- package/framework/components/chui_toast_queue/styles.css +11 -11
- package/framework/components/chui_toast_queue/toast_queue.js +30 -27
- package/framework/components/chui_toolbar/styles.css +2 -2
- package/framework/components/chui_tooltip/styles.css +2 -2
- package/framework/components/chui_tooltip/tooltip.js +3 -3
- package/framework/components/chui_tour/styles.css +8 -8
- package/framework/components/chui_tour/tour.js +72 -72
- package/framework/components/chui_transfer/styles.css +6 -6
- package/framework/components/chui_transfer/transfer.js +93 -106
- package/framework/components/chui_tree_table/styles.css +4 -4
- package/framework/components/chui_tree_table/tree_table.js +45 -45
- package/framework/components/chui_tree_view/styles.css +10 -8
- package/framework/components/chui_tree_view/tree_view.js +185 -183
- 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 +17 -17
- package/framework/components/chui_webview/webview.js +9 -9
- 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 +78 -79
- package/framework/modules/chui_animations/animations.js +77 -15
- package/framework/modules/chui_animations/motion.js +120 -0
- package/framework/modules/chui_animations/styles.css +36 -3
- package/framework/modules/chui_functions.js +31 -27
- package/framework/modules/chui_highlight/styles.css +13 -10
- package/framework/modules/chui_i18n/chui_i18n.js +3 -3
- package/framework/modules/chui_i18n/locales/feedback.js +62 -0
- package/framework/modules/chui_i18n/locales/navigation.js +4 -0
- package/framework/modules/chui_json/chui_json.js +2 -2
- package/framework/modules/chui_logger/chui_logger.js +23 -8
- package/framework/modules/chui_page/page.js +10 -10
- package/framework/modules/chui_palette/palette.js +61 -0
- package/framework/modules/chui_qr/chui_qr.js +23 -23
- package/framework/modules/chui_scrollbar/chui_scrollbar.js +45 -45
- package/framework/modules/chui_scrollbar/styles.css +3 -3
- package/framework/modules/chui_services/chui_services.js +8 -8
- package/framework/modules/chui_services/desktop.js +77 -71
- package/framework/modules/chui_sortable/chui_sortable.js +17 -17
- package/framework/modules/chui_validate/chui_validate.js +3 -3
- package/framework/tray_bar/chui_menu_items.js +2 -2
- package/index.d.ts +266 -34
- package/index.js +20 -1168
- package/package.json +6 -4
- package/framework/components/telegram_bot/chui_telegram_bot.js +0 -191
|
@@ -1,97 +1,42 @@
|
|
|
1
|
-
const {
|
|
2
|
-
const { setStyles, getTime, optionOr } = require("../../modules/chui_functions");
|
|
3
|
-
const { LAYOUT_ROLE, requireLayoutNode } = require("../../modules/chui_layout/chui_layout");
|
|
1
|
+
const { optionOr } = require("../../modules/chui_functions");
|
|
4
2
|
const { Icons } = require("../chui_icons/icons");
|
|
5
|
-
//
|
|
6
|
-
const {
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
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
|
+
// Пустая заготовка опции равносильна отсутствующей: текст хода обязателен
|
|
25
23
|
const text = optionOr(options.text, undefined);
|
|
26
|
-
if (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
throw new Error("Должна быть установлена опция title");
|
|
30
|
-
}
|
|
31
|
-
this.#download_notification_body.style.width = "-webkit-fill-available";
|
|
32
|
-
this.#download_notification_date.innerHTML = getTime();
|
|
33
|
-
if (text !== undefined) {
|
|
34
|
-
this.#download_notification_text.innerText = text;
|
|
35
|
-
} else {
|
|
36
|
-
throw new Error("Должна быть установлена опция text");
|
|
37
|
-
}
|
|
38
|
-
this.#download_notification_header.appendChild(this.#download_notification_title);
|
|
39
|
-
this.#download_notification_header.appendChild(this.#download_notification_date);
|
|
40
|
-
this.#download_notification_content.appendChild(this.#download_notification_header);
|
|
41
|
-
this.#download_notification_body.appendChild(this.#download_notification_text);
|
|
42
|
-
this.#download_notification_content.appendChild(this.#download_notification_body);
|
|
43
|
-
// Значок состояния — в плашке слева, как у Notification
|
|
44
|
-
this.#download_notification_icon = createStatusPlate(undefined, Icons.FILE.DOWNLOAD_FOR_OFFLINE);
|
|
45
|
-
this.#download_notification.appendChild(this.#download_notification_icon);
|
|
46
|
-
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);
|
|
47
27
|
}
|
|
48
28
|
update(title = String(), text = String()) {
|
|
49
|
-
this.#
|
|
50
|
-
this.#
|
|
29
|
+
this.#card.title.innerText = title;
|
|
30
|
+
this.#text.innerText = text;
|
|
51
31
|
}
|
|
52
32
|
show() {
|
|
53
|
-
|
|
54
|
-
const panel = requireLayoutNode(LAYOUT_ROLE.NOTIFICATION_PANEL, this.#download_notification);
|
|
55
|
-
panel.appendChild(this.#download_notification);
|
|
56
|
-
new Animation(this.#download_notification).slideRightIn();
|
|
57
|
-
this.#download_notification.addEventListener("click", () =>
|
|
58
|
-
this.#hideNotification(this.#download_notification)
|
|
59
|
-
);
|
|
33
|
+
showDownloadCard(this.#card);
|
|
60
34
|
}
|
|
61
35
|
done() {
|
|
62
|
-
this.#
|
|
36
|
+
finishDownloadCard(this.#card, "success");
|
|
63
37
|
}
|
|
64
38
|
error() {
|
|
65
|
-
this.#
|
|
66
|
-
}
|
|
67
|
-
/** Итог загрузки: цвет статуса несут класс карточки и плашка значка */
|
|
68
|
-
#renderTest(className, status) {
|
|
69
|
-
const notification = this.#download_notification;
|
|
70
|
-
notification.className = className;
|
|
71
|
-
// Ошибку объявляем сразу, успех — вежливо (как у `Toast`)
|
|
72
|
-
notification.setAttribute("role", status === "error" ? "alert" : "status");
|
|
73
|
-
setStatusPlate(this.#download_notification_icon, status);
|
|
74
|
-
setTimeout(() => this.#hideNotification(notification), 2000);
|
|
75
|
-
}
|
|
76
|
-
#hideNotification(notification) {
|
|
77
|
-
new Animation(notification).slideRightOutAndRemove();
|
|
78
|
-
notification.addEventListener("animationend", () => {
|
|
79
|
-
// Точечный сброс следов анимации вместо стирания всего атрибута `style`
|
|
80
|
-
notification.style.removeProperty("animation-name");
|
|
81
|
-
notification.style.removeProperty("transition");
|
|
82
|
-
notification.style.display = "flex";
|
|
83
|
-
notification.style.width = "-webkit-fill-available";
|
|
84
|
-
notification.style.opacity = "0";
|
|
85
|
-
notification.style.transform = "translateX(100%)";
|
|
86
|
-
let box = requireLayoutNode(LAYOUT_ROLE.NOTIFICATION_BOX_MAIN, notification);
|
|
87
|
-
// В истории запись плоская и без курсора: класс снимает стекло, тень и отклик на наведение
|
|
88
|
-
notification.classList.add("notification_in_box");
|
|
89
|
-
box.appendChild(notification);
|
|
90
|
-
setTimeout(() => {
|
|
91
|
-
notification.style.opacity = "1";
|
|
92
|
-
notification.style.transform = "translateX(0)";
|
|
93
|
-
}, 500);
|
|
94
|
-
});
|
|
39
|
+
finishDownloadCard(this.#card, "error");
|
|
95
40
|
}
|
|
96
41
|
}
|
|
97
42
|
|
|
@@ -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);
|
|
@@ -130,7 +130,7 @@ download_progress_count {
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
.download_progress_bar::-webkit-progress-bar {
|
|
133
|
-
background: var(--
|
|
133
|
+
background: var(--player_background);
|
|
134
134
|
border-radius: var(--radius_pill);
|
|
135
135
|
border: none;
|
|
136
136
|
}
|
|
@@ -1,122 +1,84 @@
|
|
|
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
1
|
const { I18n } = require("../../modules/chui_i18n/chui_i18n");
|
|
5
2
|
const { Icons } = require("../chui_icons/icons");
|
|
6
|
-
//
|
|
7
|
-
const {
|
|
3
|
+
// Каркас карточки загрузки — общий с `DownloadNotification` (см. модуль)
|
|
4
|
+
const { createDownloadCard, showDownloadCard, finishDownloadCard } = require("./notification_download_card");
|
|
8
5
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
#download_notification_body = document.createElement("download_notification_body");
|
|
19
|
-
//
|
|
20
|
-
#id_progress = require("randomstring").generate();
|
|
21
|
-
#ProgressBar = document.createElement(`progress`);
|
|
22
|
-
#main = document.createElement("download_progress_block");
|
|
23
|
-
#progress_text_block = document.createElement("download_progress_text_block");
|
|
24
|
-
#id_progress_count = require("randomstring").generate();
|
|
25
|
-
#progress_count = document.createElement("download_progress_count");
|
|
26
|
-
#id_progress_text = require("randomstring").generate();
|
|
27
|
-
#progress_text = document.createElement("download_progress_text");
|
|
28
|
-
constructor(options = { title: String(), text: String(), type: String() }) {
|
|
29
|
-
setStyles(__dirname + "/notification_download_progress.css", "chUiJS_downloadProgressNotification");
|
|
30
|
-
this.#download_notification.id = this.#id;
|
|
31
|
-
// Ход загрузки объявляется вежливо; итог с ошибкой меняет роль в `#renderTest()`
|
|
32
|
-
this.#download_notification.setAttribute("role", "status");
|
|
33
|
-
this.#download_notification_title.id = this.#id_download_notification_title;
|
|
34
|
-
// Пустая заготовка опции равносильна отсутствующей
|
|
35
|
-
if (optionOr(options.title, undefined) !== undefined) {
|
|
36
|
-
this.#download_notification_title.innerText = options.title;
|
|
37
|
-
} else {
|
|
38
|
-
throw new Error("Должна быть установлена опция title");
|
|
39
|
-
}
|
|
40
|
-
this.#download_notification_body.style.width = "-webkit-fill-available";
|
|
41
|
-
this.#download_notification_date.innerHTML = getTime();
|
|
42
|
-
this.#download_notification_header.appendChild(this.#download_notification_title);
|
|
43
|
-
this.#download_notification_header.appendChild(this.#download_notification_date);
|
|
44
|
-
this.#download_notification_content.appendChild(this.#download_notification_header);
|
|
45
|
-
this.#download_notification_content.appendChild(this.#download_notification_body);
|
|
46
|
-
// Значок состояния — в плашке слева, как у Notification
|
|
47
|
-
this.#download_notification_icon = createStatusPlate(undefined, Icons.FILE.DOWNLOADING);
|
|
48
|
-
this.#download_notification.appendChild(this.#download_notification_icon);
|
|
49
|
-
this.#download_notification.appendChild(this.#download_notification_content);
|
|
50
|
-
|
|
51
|
-
//
|
|
52
|
-
if (options.max !== undefined) this.#ProgressBar.max = options.max;
|
|
53
|
-
this.#ProgressBar.id = this.#id_progress;
|
|
54
|
-
this.#ProgressBar.className = "download_progress_bar";
|
|
55
|
-
this.#progress_count.id = this.#id_progress_count;
|
|
56
|
-
this.#progress_count.setAttribute("for", this.#id_progress);
|
|
57
|
-
this.#progress_text.id = this.#id_progress_text;
|
|
58
|
-
this.#progress_text.setAttribute("for", this.#id_progress);
|
|
59
|
-
this.#progress_text_block.appendChild(this.#progress_text);
|
|
60
|
-
this.#progress_text_block.appendChild(this.#progress_count);
|
|
6
|
+
/**
|
|
7
|
+
* Число для дорожки прогресса. `<progress>` не принимает `NaN` (бросает `TypeError`), а в счётчике
|
|
8
|
+
* он печатался бы как «NaN из NaN». Поэтому нечисловое значение читается как «не передали»:
|
|
9
|
+
* шкала и счётчик остаются на прежнем месте.
|
|
10
|
+
*/
|
|
11
|
+
function countValue(raw = undefined) {
|
|
12
|
+
const value = Number(raw);
|
|
13
|
+
return Number.isFinite(value) ? value : undefined;
|
|
14
|
+
}
|
|
61
15
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Уведомление о загрузке с дорожкой прогресса: название, текст, счётчик «N из M» и итог.
|
|
18
|
+
*
|
|
19
|
+
* Тело — дорожка со счётчиком, поэтому оно не входит в общий каркас: у карточек общими
|
|
20
|
+
* остаются шапка с датой, статус и уход в историю (см. `notification_download_card.js`).
|
|
21
|
+
*/
|
|
22
|
+
class DownloadProgressNotification {
|
|
23
|
+
#card;
|
|
24
|
+
#progress = document.createElement("progress");
|
|
25
|
+
#text = document.createElement("download_progress_text");
|
|
26
|
+
#count = document.createElement("download_progress_count");
|
|
27
|
+
constructor(options = { title: String(), text: String(), type: String(), max: Number() }) {
|
|
28
|
+
this.#card = createDownloadCard({
|
|
29
|
+
tag: "notification_download_progress",
|
|
30
|
+
styles: { file: "notification_download_progress.css", id: "chUiJS_downloadProgressNotification" },
|
|
31
|
+
glyph: Icons.FILE.DOWNLOADING,
|
|
32
|
+
title: options.title,
|
|
33
|
+
});
|
|
34
|
+
// Шкала объявляет себя скринридеру сама; подписи связаны с ней по `for`
|
|
35
|
+
this.#progress.id = require("randomstring").generate();
|
|
36
|
+
this.#progress.className = "download_progress_bar";
|
|
37
|
+
const max = countValue(options.max);
|
|
38
|
+
if (max !== undefined && max > 0) this.#progress.max = max;
|
|
39
|
+
this.#text.id = require("randomstring").generate();
|
|
40
|
+
this.#text.setAttribute("for", this.#progress.id);
|
|
41
|
+
this.#count.id = require("randomstring").generate();
|
|
42
|
+
this.#count.setAttribute("for", this.#progress.id);
|
|
43
|
+
this.#text.innerText = "...";
|
|
44
|
+
this.#count.innerText = I18n.t("feedback.progressCount", { value: 0, max: 0 });
|
|
45
|
+
this.#progress.value = 0;
|
|
46
|
+
const textBlock = document.createElement("download_progress_text_block");
|
|
47
|
+
textBlock.appendChild(this.#text);
|
|
48
|
+
textBlock.appendChild(this.#count);
|
|
49
|
+
const block = document.createElement("download_progress_block");
|
|
50
|
+
block.appendChild(textBlock);
|
|
51
|
+
block.appendChild(this.#progress);
|
|
52
|
+
block.style.width = "-webkit-fill-available";
|
|
53
|
+
this.#card.body.appendChild(block);
|
|
70
54
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Обновление хода загрузки.
|
|
57
|
+
*
|
|
58
|
+
* Числа могут не прийти (загрузка без известного размера) или быть нечисловыми — тогда
|
|
59
|
+
* шкала и счётчик остаются на прежнем месте. Прежде умолчаниями стояли `Number()`: вызов
|
|
60
|
+
* `update(title, text)` обнулял шкалу и менял `max` (ноль браузер молча заменяет единицей),
|
|
61
|
+
* а нечисловое значение бросало `TypeError` прямо в обработчике хода загрузки.
|
|
62
|
+
*/
|
|
63
|
+
update(title = String(), text = String(), value = undefined, max = undefined) {
|
|
64
|
+
this.#card.title.innerText = title;
|
|
65
|
+
this.#text.innerText = text;
|
|
66
|
+
const total = countValue(max);
|
|
67
|
+
const done = countValue(value);
|
|
68
|
+
if (total !== undefined && total > 0) this.#progress.max = total;
|
|
69
|
+
if (done !== undefined) this.#progress.value = Math.max(0, done);
|
|
70
|
+
if (done !== undefined && total !== undefined) {
|
|
71
|
+
this.#count.innerText = I18n.t("feedback.progressCount", { value: done, max: total });
|
|
72
|
+
}
|
|
77
73
|
}
|
|
78
74
|
show() {
|
|
79
|
-
|
|
80
|
-
panel.appendChild(this.#download_notification);
|
|
81
|
-
new Animation(this.#download_notification).slideRightIn();
|
|
82
|
-
this.#download_notification.addEventListener("click", () =>
|
|
83
|
-
this.#hideNotification(this.#download_notification)
|
|
84
|
-
);
|
|
75
|
+
showDownloadCard(this.#card);
|
|
85
76
|
}
|
|
86
77
|
done() {
|
|
87
|
-
this.#
|
|
78
|
+
finishDownloadCard(this.#card, "success");
|
|
88
79
|
}
|
|
89
80
|
error() {
|
|
90
|
-
this.#
|
|
91
|
-
}
|
|
92
|
-
/** Итог загрузки: цвет статуса несут класс карточки и плашка значка */
|
|
93
|
-
#renderTest(className, status) {
|
|
94
|
-
const notification = this.#download_notification;
|
|
95
|
-
notification.className = className;
|
|
96
|
-
// Ошибку объявляем сразу, успех — вежливо (как у `Toast`)
|
|
97
|
-
notification.setAttribute("role", status === "error" ? "alert" : "status");
|
|
98
|
-
setStatusPlate(this.#download_notification_icon, status);
|
|
99
|
-
setTimeout(() => this.#hideNotification(notification), 2000);
|
|
100
|
-
}
|
|
101
|
-
#hideNotification(notification) {
|
|
102
|
-
new Animation(notification).slideRightOutAndRemove();
|
|
103
|
-
notification.addEventListener("animationend", () => {
|
|
104
|
-
// Точечный сброс следов анимации вместо стирания всего атрибута `style`
|
|
105
|
-
notification.style.removeProperty("animation-name");
|
|
106
|
-
notification.style.removeProperty("transition");
|
|
107
|
-
notification.style.display = "flex";
|
|
108
|
-
notification.style.width = "-webkit-fill-available";
|
|
109
|
-
notification.style.opacity = "0";
|
|
110
|
-
notification.style.transform = "translateX(100%)";
|
|
111
|
-
let box = requireLayoutNode(LAYOUT_ROLE.NOTIFICATION_BOX_MAIN, notification);
|
|
112
|
-
// В истории запись плоская и без курсора: класс снимает стекло, тень и отклик на наведение
|
|
113
|
-
notification.classList.add("notification_in_box");
|
|
114
|
-
box.appendChild(notification);
|
|
115
|
-
setTimeout(() => {
|
|
116
|
-
notification.style.opacity = "1";
|
|
117
|
-
notification.style.transform = "translateX(0)";
|
|
118
|
-
}, 500);
|
|
119
|
-
});
|
|
81
|
+
finishDownloadCard(this.#card, "error");
|
|
120
82
|
}
|
|
121
83
|
}
|
|
122
84
|
|
|
@@ -8,76 +8,76 @@ const { createStatusPlate } = require("./status_plate");
|
|
|
8
8
|
|
|
9
9
|
class UpdateNotification {
|
|
10
10
|
#id = require("randomstring").generate();
|
|
11
|
-
#
|
|
12
|
-
#
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
18
|
-
#
|
|
11
|
+
#updateNotification = document.createElement(`update_notification`);
|
|
12
|
+
#updateNotificationIcon = undefined;
|
|
13
|
+
#updateNotificationContent = document.createElement("update_notification_content");
|
|
14
|
+
#updateNotificationHeader = document.createElement("update_notification_header");
|
|
15
|
+
#updateNotificationTitle = document.createElement("update_notification_title");
|
|
16
|
+
#updateNotificationDate = document.createElement("update_notification_date");
|
|
17
|
+
#updateNotificationBody = document.createElement("update_notification_body");
|
|
18
|
+
#updateNotificationText = document.createElement("update_notification_text");
|
|
19
19
|
constructor(options = { title: String(), text: String(), spinner: Boolean() }) {
|
|
20
20
|
setStyles(__dirname + "/styles_update.css", "chUiJS_UpdateNotification");
|
|
21
|
-
this.#
|
|
21
|
+
this.#updateNotification.id = this.#id;
|
|
22
22
|
// Карточка обновления живёт в ящике и меняется на месте — объявляем вежливо
|
|
23
|
-
this.#
|
|
23
|
+
this.#updateNotification.setAttribute("role", "status");
|
|
24
24
|
// Пустая заготовка опции равносильна отсутствующей: пустое уведомление не собирается
|
|
25
25
|
const title = optionOr(options.title, undefined);
|
|
26
26
|
const text = optionOr(options.text, undefined);
|
|
27
27
|
// Стили заголовка уведомления
|
|
28
28
|
if (title !== undefined) {
|
|
29
|
-
this.#
|
|
29
|
+
this.#updateNotificationTitle.innerText = title;
|
|
30
30
|
} else {
|
|
31
31
|
throw new Error("Должна быть установлена опция title");
|
|
32
32
|
}
|
|
33
33
|
// Стили текста уведомления
|
|
34
34
|
if (text !== undefined) {
|
|
35
|
-
this.#
|
|
35
|
+
this.#updateNotificationText.innerText = text;
|
|
36
36
|
} else {
|
|
37
37
|
throw new Error("Должна быть установлена опция text");
|
|
38
38
|
}
|
|
39
|
-
this.#
|
|
39
|
+
this.#updateNotificationDate.innerHTML = getTime();
|
|
40
40
|
//
|
|
41
|
-
this.#
|
|
42
|
-
this.#
|
|
41
|
+
this.#updateNotificationHeader.appendChild(this.#updateNotificationTitle);
|
|
42
|
+
this.#updateNotificationHeader.appendChild(this.#updateNotificationDate);
|
|
43
43
|
//
|
|
44
|
-
this.#
|
|
44
|
+
this.#updateNotificationContent.appendChild(this.#updateNotificationHeader);
|
|
45
45
|
// Значок и спиннер делят одно место — плашку слева: карточка остаётся ровной,
|
|
46
46
|
// а текст не отъезжает вбок под вращающимся кольцом
|
|
47
|
-
this.#
|
|
47
|
+
this.#updateNotificationIcon = createStatusPlate(undefined, Icons.NOTIFICATION.SYSTEM_UPDATE);
|
|
48
48
|
if (options.spinner) {
|
|
49
49
|
// Под кольцом заливки нет: плашка держит только место значка, иначе серая подложка
|
|
50
50
|
// читалась вторым фоном вокруг тонкого индикатора
|
|
51
|
-
this.#
|
|
52
|
-
this.#
|
|
53
|
-
this.#
|
|
51
|
+
this.#updateNotificationIcon.classList.add("notification_icon_plain");
|
|
52
|
+
this.#updateNotificationIcon.innerHTML = "";
|
|
53
|
+
this.#updateNotificationIcon.appendChild(new Spinner(Spinner.SIZE.V_SMALL, "0").set());
|
|
54
54
|
}
|
|
55
|
-
this.#
|
|
56
|
-
this.#
|
|
57
|
-
this.#
|
|
58
|
-
this.#
|
|
55
|
+
this.#updateNotificationBody.appendChild(this.#updateNotificationText);
|
|
56
|
+
this.#updateNotificationContent.appendChild(this.#updateNotificationBody);
|
|
57
|
+
this.#updateNotification.appendChild(this.#updateNotificationIcon);
|
|
58
|
+
this.#updateNotification.appendChild(this.#updateNotificationContent);
|
|
59
59
|
}
|
|
60
60
|
show(showOnSystem = Boolean()) {
|
|
61
|
-
const panel = requireLayoutNode(LAYOUT_ROLE.NOTIFICATION_PANEL, this.#
|
|
62
|
-
panel.appendChild(this.#
|
|
63
|
-
new Animation(this.#
|
|
61
|
+
const panel = requireLayoutNode(LAYOUT_ROLE.NOTIFICATION_PANEL, this.#updateNotification);
|
|
62
|
+
panel.appendChild(this.#updateNotification);
|
|
63
|
+
new Animation(this.#updateNotification).slideRightIn();
|
|
64
64
|
//notification.addEventListener("click", () => this.hide(notification));
|
|
65
65
|
if (showOnSystem)
|
|
66
66
|
require("electron").ipcRenderer.send(
|
|
67
67
|
"show_system_notification",
|
|
68
|
-
this.#
|
|
69
|
-
this.#
|
|
68
|
+
this.#updateNotificationTitle.innerText,
|
|
69
|
+
this.#updateNotificationText.innerText
|
|
70
70
|
);
|
|
71
71
|
}
|
|
72
72
|
hide() {
|
|
73
|
-
const notification = this.#
|
|
73
|
+
const notification = this.#updateNotification;
|
|
74
74
|
// Карточка обновления не уезжает в ящик истории: после анимации её убираем совсем.
|
|
75
75
|
// Без этого невидимый узел копился в панели уведомлений на каждое объявление
|
|
76
76
|
notification.addEventListener("animationend", (event) => {
|
|
77
77
|
if (event.target !== notification) return;
|
|
78
78
|
notification.remove();
|
|
79
79
|
});
|
|
80
|
-
new Animation(this.#
|
|
80
|
+
new Animation(this.#updateNotification).slideRightOutAndRemove();
|
|
81
81
|
// Карточку ещё не показывали — анимации не будет, но узел в панели остался бы висеть
|
|
82
82
|
if (notification.style.animationName === "" && document.body.contains(notification)) notification.remove();
|
|
83
83
|
}
|
|
@@ -22,17 +22,17 @@ notification_icon chui_icon {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
notification_icon.notification_icon_success {
|
|
25
|
-
background: var(--
|
|
25
|
+
background: var(--badge_success_background);
|
|
26
26
|
color: var(--badge_success_text);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
29
|
notification_icon.notification_icon_warning {
|
|
30
|
-
background: var(--
|
|
30
|
+
background: var(--badge_warning_background);
|
|
31
31
|
color: var(--badge_warning_text);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
notification_icon.notification_icon_error {
|
|
35
|
-
background: var(--
|
|
35
|
+
background: var(--badge_error_background);
|
|
36
36
|
color: var(--badge_error_text);
|
|
37
37
|
}
|
|
38
38
|
|
|
@@ -9,7 +9,7 @@ notification {
|
|
|
9
9
|
Статус несёт не акцентная полоса слева (устаревший приём «предупредительной
|
|
10
10
|
рамки»), а плашка значка и цветной волосяной край `border-color` ниже. */
|
|
11
11
|
border-radius: var(--radius_md);
|
|
12
|
-
margin: var(--
|
|
12
|
+
margin: var(--block_margin);
|
|
13
13
|
font-size: var(--font_default_size);
|
|
14
14
|
padding: 12px 14px;
|
|
15
15
|
background: var(--header_background);
|
|
@@ -128,7 +128,12 @@ notification_progress {
|
|
|
128
128
|
|
|
129
129
|
/* Плоская поверхность списка: записи истории не «всплывают» над панелью и не размывают её */
|
|
130
130
|
.notification_in_box {
|
|
131
|
+
/* Вид записи истории и показывает карточку: вне ящика `notification` скрыт (`display: none`),
|
|
132
|
+
поэтому запись показывает себя сама — инлайновый `display` из JS ушёл вместе с ручной
|
|
133
|
+
уборкой следов кадра */
|
|
134
|
+
display: flex;
|
|
131
135
|
/* в списке истории карточка тянется по ширине ящика, а не держит ширину тоста */
|
|
136
|
+
width: -webkit-fill-available;
|
|
132
137
|
min-width: 0;
|
|
133
138
|
max-width: -webkit-fill-available;
|
|
134
139
|
margin: 4px 2px;
|
|
@@ -7,7 +7,7 @@ download_notification {
|
|
|
7
7
|
box-sizing: border-box;
|
|
8
8
|
/* Тот же материал и ритм, что у карточки Notification */
|
|
9
9
|
border-radius: var(--radius_md);
|
|
10
|
-
margin: var(--
|
|
10
|
+
margin: var(--block_margin);
|
|
11
11
|
font-size: var(--font_default_size);
|
|
12
12
|
padding: 12px 14px;
|
|
13
13
|
background: var(--header_background);
|
|
@@ -8,7 +8,7 @@ update_notification {
|
|
|
8
8
|
/* Тот же материал и тот же ритм, что у карточки Notification: стеклянная
|
|
9
9
|
поверхность, радиус, волосяной край и отступы 12/14 */
|
|
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);
|
|
@@ -27,7 +27,7 @@ update_notification_body {
|
|
|
27
27
|
display: flex;
|
|
28
28
|
flex-direction: row;
|
|
29
29
|
align-items: center;
|
|
30
|
-
gap: var(--
|
|
30
|
+
gap: var(--block_margin);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
update_notification_content {
|