{tt('app_settings.blogs_service')}
diff --git a/src/foundation-overrides.scss b/src/foundation-overrides.scss
index c9e9f17a3..ea7d0629d 100644
--- a/src/foundation-overrides.scss
+++ b/src/foundation-overrides.scss
@@ -11,9 +11,15 @@
border-radius: 6px;
background-color: #fff;
box-shadow: 0 2px 12px 0 rgba(0,0,0,0.15), 0 2px 12px 0 rgba(0,0,0,0.15);
+ &.fade {
+ opacity: 0;
+ transition: opacity 100ms linear;
+ }
+ &.in {
+ opacity: 1;
+ }
}
-
div[role=dialog] {
z-index: 500;
}
diff --git a/src/locales/en.json b/src/locales/en.json
index 91abf9e1b..3f0dbb4e7 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -1,4 +1,32 @@
{
+ "account_dropdown_jsx": {
+ "clear_history": "Clear Hstory",
+ "delete_chat": "Delete Chat",
+ "are_you_sure": "Are you sure you want to clear history?",
+ "are_you_sure_delete": "Are you sure you want to clear history and delete chat?",
+ "are_you_sure_delete_empty": "Are you sure you want to delete chat?"
+ },
+ "account_name": {
+ "account_name_should_be_shorter": "Account name should be shorter.",
+ "account_name_should_be_longer": "Account name should be longer.",
+ "account_name_should_not_be_empty": "Account name should not be empty.",
+ "each_account_segment_should_start_with_a_letter": "Each account name segment should start with a letter.",
+ "each_account_segment_should_have_only_letters_digits_or_dashes": "Each account name segment should have only letters, digits or dashes.",
+ "each_account_segment_should_have_only_one_dash_in_a_row": "Each account name segment should have only one dash in a row.",
+ "each_account_segment_should_end_with_a_letter_or_digit": "Each account name segment should end with a letter or digit.",
+ "each_account_segment_should_be_longer": "Each account name segment should be longer."
+ },
+ "account_name_jsx": {
+ "loading": "Loading...",
+ "no_options": "Cannot search..."
+ },
+ "chain_errors": {
+ "exceeded_maximum_allowed_bandwidth": "Insufficient account bandwidth. Replenish the Golos Power or write to info@golos.id",
+ "insufficient1": "It costs ",
+ "insufficient2": ", but you have just ",
+ "insufficient3": ". ",
+ "insufficient_top_up": "Top Up"
+ },
"chainvalidation_js": {
"account_name_should": "Account name should ",
"not_be_empty": "not be empty.",
@@ -33,6 +61,8 @@
"login_to_post": "Login to Post",
"login_to_comment": "Login to Comment",
"login_to_message": "Login with Memo Key or Password",
+ "login_active": "Enter password (or active-key)",
+ "is_is_for_operation": "This is to send an operation.",
"login_to_your_steem_account": "Login to your Steem Account",
"login_with_active_key_USERNAME": "Login with your Active key, please\n\nUsername:\n%(USERNAME)s\n\nActive-key:\n",
"posting": "Posting",
@@ -59,6 +89,11 @@
"join_our": "Join our",
"account_frozen": "This account is temporarily frozen due to inactivity."
},
+ "login_dialog_jsx": {
+ "node_failure_NODE_ERROR": "Node failure. Node: %(NODE)s Error: %(ERROR)s",
+ "wrong_pass": "Wrong password.",
+ "wrong_pass_ROLE": "Wrong password. No access to %(ROLE)s permissions."
+ },
"messages": {
"last_seen": "last seen ",
"verified_golos_account": "Verified account of Golos staff",
@@ -72,10 +107,130 @@
"new_message5": " notifications",
"invalid_message": "(This message could not be displayed in Golos Messenger)",
"sync_error": "Sync error. To receive new messages please refresh the page.",
- "sync_error_short": "Sync error. To receive new messages touch ",
+ "sync_error_short": "Sync error. ",
"blocked_BY": "You are blocked by @%(BY)s.",
"do_not_bother_BY": "@%(BY)s wants to not be bothered by low-reputation users."
},
+ "msgs_group_dropdown": {
+ "join": "Join",
+ "retire": "Retire",
+ "cancel": "Cancel",
+ "public": "Public group",
+ "read_only": "Public only as read-only",
+ "private": "Private group",
+ "encrypted": "Messages are encrypted",
+ "not_encrypted": "Messages are not encrypted",
+ "banned": "You are banned.",
+ "pending": "You requested membership.",
+ "moder": "You are moderator.",
+ "owner": "You are owner.",
+ "are_you_sure_retire": "Are you sure you want to retire from ",
+ "joining_back_will_require_approval": "Joining it back will require approval."
+ },
+ "msgs_start_panel": {
+ "start_chat": "Start chat",
+ "create_group": "Create group"
+ },
+ "msgs_chat_error": {
+ "404_group": "We have not such group",
+ "404_acc": "No such account",
+ "404_but": "But we have many interesting things...",
+ "500_group": "Error",
+ "500_load_msgs": "Cannot load messages."
+ },
+ "create_group_jsx": {
+ "title": "Title",
+ "name": "Link chat.golos.app/",
+ "logo": "Logo",
+ "admin": "Admin",
+ "encrypted": "Encrypt messages in group",
+ "encrypted_hint": "Шифрование позволяет сделать сообщения доступными только тем, кто имеет доступ к группе.",
+ "encrypted_dis": " (required for privacy)",
+ "access": "Access to group for...",
+ "access_hint": "Можно сделать группу открытой, или доступной только тем, чьи заявки на вступление в группу одобрит администрация.",
+ "access_all": "Everyone",
+ "all_read_only": "Everyone, but posting only for members",
+ "access_private": "Only members",
+ "next": "Next",
+ "back": "Back",
+ "submit": "Create",
+ "step_name": "Name",
+ "step_logo": "Logo",
+ "step_logo_mobile": "Logo",
+ "step_members": "Members",
+ "step_members_mobile": "Membs",
+ "step_create": "Create!",
+ "step_create_mobile": "Go!",
+ "group_already_exists": "Group already exists.",
+ "group_min_length": "Min is 3 symbols.",
+ "golos_power_too_low": "To create group you should have Golos Power at least ",
+ "golos_power_too_low2": "That is not enough ",
+ "golos_power_too_low3": "Your Golos Power is ",
+ "gbg_too_low": "Group creation costs ",
+ "gbg_too_low2": "That is not enough ",
+ "gbg_too_low3": "Your GBG balance is ",
+ "create_of_group_is": "Creating of group is ",
+ "free": "free",
+ "deposit_gp": "Increase Golos Power",
+ "logo_desc": "The group logo is like a user’s avatar... Not required, but \"must have\"...",
+ "logo_upload": "Upload logo",
+ "logo_link": "Add logo from the URL",
+ "members_desc": "Add people, set moderators of the group...",
+ "final_desc": "Now we are ready to create the group!",
+ "moders_list": "Moderators:",
+ "members_list": "Members:",
+ "image_wrong": "Cannot load this image.",
+ "image_timeout": "Cannot load this image, it is loading too long...",
+ "add_member": "+ Add Member..."
+ },
+ "my_groups_jsx": {
+ "title": "My Groups",
+ "empty": "You have not any groups yet. ",
+ "empty2": "You can ",
+ "find": "find",
+ "find2": "interesting group",
+ "create": "create",
+ "create2": "your own one",
+ "create_more": "+ Create a group",
+ "more_groups": "More groups...",
+ "edit": "Edit",
+ "login_hint_GROUP": "(delete \"%(GROUP)s\" group)",
+ "members": "Members",
+ "cancel_pending": "Cancel request",
+ "are_you_sure_cancel": "Do you sure you don't want to join"
+ },
+ "top_groups_jsx": {
+ "title": "Popular Groups",
+ "empty": "We have no groups yet. ",
+ "empty2": "Become the first - ",
+ "create": "create your own group!",
+ "public": "Public",
+ "read_only": "Read-only",
+ "private": "Private"
+ },
+ "group_members_jsx": {
+ "title": "Members Of ",
+ "title2": " Group",
+ "check_pending": "Requests",
+ "check_pending_hint": "Pending Group Join Requests",
+ "check_banned": "Blocked",
+ "all": "All",
+ "moders": "Moderators",
+ "member": "Member",
+ "moder": "Moderator",
+ "owner": "Group Owner",
+ "make_member": "Make Simple Member",
+ "make_moder": "Make Moderator",
+ "ban": "Ban",
+ "unban": "Unban",
+ "banned": "Banned"
+ },
+ "group_settings_jsx": {
+ "title_GROUP": "%(GROUP)s Group",
+ "submit": "Save",
+ "owner": "Owner",
+ "upload": "Upload"
+ },
"emoji_i18n": {
"categoriesLabel": "Категории",
"emojiUnsupportedMessage": "Ваш браузер не поддерживает эмодзи.",
@@ -110,6 +265,15 @@
"flags": "Флаги"
}
},
+ "stub_jsx": {
+ "read_only": "Only members can post messages in this group.",
+ "private_group": "This group is private. To read and write messages, you should be a member.",
+ "pending": "You issued request to join group.",
+ "banned": "You banned in this group.",
+ "join": "Make Request",
+ "blocked": "User blocked you.",
+ "blocking": "You are blocked by user."
+ },
"user_saga_js": {
"image_upload": {
"uploading": "Uploading",
@@ -152,7 +316,8 @@
"current_node": "GOLOS node URL",
"img_proxy_prefix": "Use Proxy For Images",
"auth_service": "Golos Auth & Registration Service (for messenger)",
- "notify_service": "Golos Notify Service (for messenger)",
+ "notify_service": "Golos Notify Service (for instant messages)",
+ "notify_service_ws": "Golos Notify Service WebSocket (for instant messages)",
"blogs_service": "Blogs",
"save": "Save",
"node_error_NODE": "Cannot connect to %(NODE)s. It may be internet failure. Try ",
@@ -172,21 +337,48 @@
"confirm": "Confirmation",
"prompt": "Enter the data"
},
+ "plurals": {
+ "member_count": {
+ "zero": "0 members",
+ "one": "1 member",
+ "other": "%(count)s members"
+ },
+ "mention_count": {
+ "zero": "0 mentions",
+ "one": "1 mention",
+ "other": "%(count)s mentions"
+ },
+ "message_count": {
+ "zero": "0 messages",
+ "one": "1 message",
+ "other": "%(count)s messages"
+ },
+ "reply_count": {
+ "zero": "0 replies",
+ "one": "1 reply",
+ "other": "%(count)s replies"
+ }
+ },
"g": {
"and": "and",
+ "block": "Block",
+ "blocked": "Blocked",
"blog": "Blog",
"cancel": "Cancel",
"delete": "Delete",
"dismiss": "Dismiss",
"edit": "Edit",
+ "groups": "Groups",
"feed": "Feed",
"incorrect_password": "Incorrect password",
"posting_not_memo": "Use posting key now, not memo",
"login": "Login",
"logout": "Logout",
"mentions": "Mentions",
+ "name": "Name",
"night_mode": "Night Mode",
"ok": "OK",
+ "or": "or",
"refresh": "Refresh",
"required": "Required",
"replies": "Replies",
@@ -195,6 +387,7 @@
"settings": "Settings",
"sign_up": "Sign Up",
"submit": "Submit",
+ "unblock": "Unblock",
"username_does_not_exist": "Username does not exist",
"wallet": "Wallet"
}
diff --git a/src/locales/ru-RU.json b/src/locales/ru-RU.json
index 65fb2f390..910190bc4 100644
--- a/src/locales/ru-RU.json
+++ b/src/locales/ru-RU.json
@@ -1,4 +1,32 @@
{
+ "account_dropdown_jsx": {
+ "clear_history": "Очистить историю",
+ "delete_chat": "Удалить чат",
+ "are_you_sure": "Вы уверены, что хотите очистить историю ",
+ "are_you_sure_delete": "Вы уверены, что хотите очистить историю и удалить чат с ",
+ "are_you_sure_delete_empty": "Вы уверены, что хотите удалить чат с "
+ },
+ "account_name": {
+ "account_name_should_be_shorter": "Имя аккаунта должно быть короче.",
+ "account_name_should_be_longer": "Имя аккаунта должно быть длиннее.",
+ "account_name_should_not_be_empty": "Имя аккаунта не должно быть пустым.",
+ "each_account_segment_should_start_with_a_letter": "Каждый сегмент имени аккаунта должен начинаться с буквы.",
+ "each_account_segment_should_have_only_letters_digits_or_dashes": "Сегмент имени аккаунта может содержать только буквы, цифры и дефисы.",
+ "each_account_segment_should_have_only_one_dash_in_a_row": "Каждый сегмент имени аккаунта может содержать только один дефис.",
+ "each_account_segment_should_end_with_a_letter_or_digit": "Каждый сегмент имени аккаунта должен заканчиваться буквой или цифрой.",
+ "each_account_segment_should_be_longer": "Сегмент имени аккаунта должен быть длиннее."
+ },
+ "account_name_jsx": {
+ "loading": "Загрузка...",
+ "no_options": "Не удается найти..."
+ },
+ "chain_errors": {
+ "exceeded_maximum_allowed_bandwidth": "Недостаточно пропускной способности аккаунта. Пополните Силу Голоса или напишите на info@golos.id",
+ "insufficient1": "Нужно ",
+ "insufficient2": ", есть ",
+ "insufficient3": ". ",
+ "insufficient_top_up": "Пополнить"
+ },
"chainvalidation_js": {
"account_name_should": "Имя аккаунта должно ",
"not_be_empty": "не может быть пустым.",
@@ -34,6 +62,8 @@
"login_to_post": "Авторизуйтесь, чтобы написать пост",
"login_to_comment": "Пожалуйста, авторизуйтесь для выполнения следующих действий",
"login_to_message": "Пожалуйста, авторизуйтесь с memo-ключом или паролем",
+ "login_active": "Введите пароль (или активный ключ)",
+ "is_is_for_operation": "Это нужно для отправки операции",
"login_with_active_key_USERNAME": "Пожалуйста, авторизуйтесь Вашим активным ключом\n\nИмя:\n%(USERNAME)s\n\nActive-ключ:\n",
"login_to_your_steem_account": "Войти в свой Голос аккаунт",
"posting": "Постинг",
@@ -60,6 +90,11 @@
"join_our": "Присоединяйтесь к нашему",
"account_frozen": "Этот аккаунт временно деактивирован из-за неактивности."
},
+ "login_dialog_jsx": {
+ "node_failure_NODE_ERROR": "Ошибка ноды. Нода: %(NODE)s Ошибка: %(ERROR)s",
+ "wrong_pass": "Неверный пароль.",
+ "wrong_pass_ROLE": "Неверный пароль. Этот ключ не дает %(ROLE)s-доступа."
+ },
"messages": {
"last_seen": "был(а) ",
"verified_golos_account": "Этот аккаунт принадлежит Golos",
@@ -73,9 +108,144 @@
"new_message5": " новых сообщений",
"invalid_message": "(Это сообщение не может быть отображено в Golos Messenger)",
"sync_error": "Ошибка синхронизации. Для получения новых сообщений обновляйте страницу.",
- "sync_error_short": "Ошибка синхронизации. Для получения новых сообщений нажимайте ",
+ "sync_error_short": "Ошибка синхронизации. ",
"blocked_BY": "Вы заблокированы пользователем @%(BY)s.",
- "do_not_bother_BY": "@%(BY)s просит пользователей с низкой репутацией не беспокоить."
+ "do_not_bother_BY": "@%(BY)s просит пользователей с низкой репутацией не беспокоить.",
+ "too_low_gp": "Не хватает Силы Голоса. Для участия в группах нужно не менее ",
+ "too_low_gp2": ".",
+ "you_not_moder": "Вы не модератор."
+ },
+ "msgs_group_dropdown": {
+ "join": "Вступить",
+ "retire": "Покинуть",
+ "cancel": "Отменить",
+ "public": "Открытая группа",
+ "read_only": "Группа, открытая только для чтения",
+ "private": "Закрытая группа",
+ "encrypted": "Сообщения шифруются",
+ "not_encrypted": "Сообщения не шифруются",
+ "banned": "Вы забанены.",
+ "pending": "Вы подали заявку на вступление.",
+ "moder": "Вы модератор.",
+ "owner": "Вы владелец.",
+ "are_you_sure_retire": "Вы уверены, что хотите покинуть группу",
+ "joining_back_will_require_approval": "Вступить обратно вы сможете только после одобрения заявки."
+ },
+ "msgs_start_panel": {
+ "start_chat": "Начать чат",
+ "create_group": "Создать группу"
+ },
+ "msgs_chat_error": {
+ "404_group": "Такой группы у нас нет",
+ "404_acc": "Такого пользователя нет",
+ "404_but": "Но у нас есть много интересного...",
+ "500_group": "Ошибка",
+ "500_load_msgs": "Не удалось загрузить сообщения."
+ },
+ "create_group_jsx": {
+ "title": "Название",
+ "name": "Ссылка chat.golos.app/",
+ "name2": "Ссылка",
+ "name3": "chat.golos.app/",
+ "logo": "Логотип",
+ "admin": "Администратор",
+ "encrypted": "Шифровать сообщения в группе",
+ "encrypted_hint": "Шифрование позволяет сделать сообщения доступными только тем, кто имеет доступ к группе.",
+ "encrypted_dis": " (в приватной обязательно)",
+ "access": "Группа будет доступна...",
+ "access_hint": "Можно сделать группу открытой, или доступной только тем, чьи заявки на вступление в группу одобрит администрация.",
+ "access_all": "Всем",
+ "all_read_only": "Всем, но постить только участникам",
+ "access_private": "Только участникам",
+ "next": "Далее",
+ "back": "Назад",
+ "submit": "Создать",
+ "step_name": "Имя",
+ "step_logo": "Логотип",
+ "step_logo_mobile": "Лого",
+ "step_members": "Участники",
+ "step_members_mobile": "Люди",
+ "step_create": "Создать!",
+ "step_create_mobile": "Go!",
+ "group_already_exists": "Такая группа уже существует.",
+ "validating": "Проверка существования группы...",
+ "group_min_length": "Минимум 3 символа.",
+ "golos_power_too_low": "Для создания группы нужна Сила Голоса не менее ",
+ "golos_power_too_low2": "Вам не хватает ",
+ "golos_power_too_low3": "Ваша Сила Голоса - ",
+ "gbg_too_low": "Создание группы стоит ",
+ "gbg_too_low2": "Вам не хватает ",
+ "gbg_too_low3": "На вашем балансе - ",
+ "create_of_group_is": "Создание группы - ",
+ "free": "бесплатно",
+ "deposit_gp": "Пополнить Силу Голоса",
+ "logo_desc": "Логотип группы - это как аватарка у пользователя... Необязательно, но \"must have\"...",
+ "logo_upload": "Загрузить логотип",
+ "logo_link": "Добавить логотип ссылкой",
+ "members_desc": "Вы можете добавить в группу людей, назначить модераторов...",
+ "final_desc": "Теперь все готово к созданию группы!",
+ "moders_list": "Модераторы группы:",
+ "members_list": "Участники:",
+ "image_wrong": "Не удается загрузить картинку.",
+ "image_timeout": "Не удается загрузить картинку, она загружается слишком долго...",
+ "add_member": "+ Добавить участника...",
+ "cannot_set_members": "Группа создана успешно. Но, к сожалению, не получилось задать участников из-за ошибки.",
+ "cannot_set_members2": "Вы можете попытаться сделать это заново в настройках группы."
+ },
+ "my_groups_jsx": {
+ "title": "Мои группы",
+ "empty": "У вас пока нет групп. ",
+ "empty2": "Вы можете ",
+ "find": "найти",
+ "find2": "интересную для себя группу",
+ "create": "создать",
+ "create2": "свою собственную",
+ "create_more": "+ Создать группу",
+ "more_groups": "Еще группы...",
+ "edit": "Изменить",
+ "login_hint_GROUP": "(удаления группы \"%(GROUP)s\")",
+ "members": "Участники",
+ "cancel_pending": "Отменить заявку",
+ "are_you_sure_cancel": "Вы уверены, что хотите отказаться от вступления в группу"
+ },
+ "top_groups_jsx": {
+ "title": "Топ популярных групп",
+ "empty": "У нас пока нет групп. ",
+ "empty2": "Станьте первым - ",
+ "create": "создайте свою группу!",
+ "public": "Открытая",
+ "read_only": "Открытая для чтения",
+ "private": "Закрытая"
+ },
+ "group_members_jsx": {
+ "title": "Участники группы ",
+ "title2": "",
+ "check_pending": "Заявки",
+ "check_pending_hint": "Заявки на вступление в группу",
+ "check_banned": "Забаненные",
+ "all": "Все",
+ "moders": "Модераторы",
+ "member": "Обычный участник",
+ "moder": "Модератор",
+ "owner": "Владелец группы",
+ "make_member": "Сделать обычным участником",
+ "make_moder": "Сделать модератором",
+ "ban": "Заблокировать",
+ "unban": "Разблокировать",
+ "banned": "Заблокирован(-а)"
+ },
+ "group_settings_jsx": {
+ "title_GROUP": "Группа %(GROUP)s",
+ "submit": "Сохранить",
+ "owner": "Владелец",
+ "upload": "Загрузить",
+ "name_cannot_change": "Ссылку на группу изменить нельзя.",
+ "preview": "(просмотр)",
+ "login_hint_GROUP": "(изменения группы \"%(GROUP)s\")",
+ "encrypted": "Сообщения в группе ",
+ "encrypted2": " шифруются.",
+ "encrypted3": " не шифруются.",
+ "encrypted_hint": "Изменить это нельзя."
},
"emoji_i18n": {
"categoriesLabel": "Категории",
@@ -111,6 +281,15 @@
"flags": "Флаги"
}
},
+ "stub_jsx": {
+ "read_only": "Писать сообщения в этой группе могут лишь ее члены.",
+ "private_group": "Это закрытая группа. Чтобы видеть сообщения и общаться в ней, надо стать ее членом.",
+ "pending": "Вы подали заявку на вступление в группу.",
+ "banned": "Вы забанены в этой группе.",
+ "join": "Подать заявку",
+ "blocked": "Пользователь заблокировал вас.",
+ "blocking": "Вы заблокировали пользователя."
+ },
"user_saga_js": {
"image_upload": {
"uploading": "Загрузка",
@@ -154,6 +333,7 @@
"img_proxy_prefix": "Использовать прокси для изображений",
"auth_service": "Golos Auth & Registration Service (для мгновенных сообщений)",
"notify_service": "Golos Notify Service (для мгновенных сообщений)",
+ "notify_service_ws": "Golos Notify Service WebSocket (для мгновенных сообщений)",
"blogs_service": "Блоги",
"save": "Сохранить",
"node_error_NODE": "Не удалось подключиться к ноде %(NODE)s. Возможно, это проблемы с интернетом. Попробуйте ",
@@ -173,21 +353,49 @@
"confirm": "Подтверждение",
"prompt": "Введите данные"
},
+ "plurals": {
+ "member_count": {
+ "zero": "0 участников",
+ "one": "1 участник",
+ "other": "%(count)s участник(-ов)"
+ },
+ "mention_count": {
+ "zero": "0 упоминания",
+ "one": "1 упоминание",
+ "other": "%(count)s упоминания(-й)"
+ },
+ "message_count": {
+ "zero": "0 сообщений",
+ "one": "1 сообщение",
+ "other": "%(count)s сообщения(-й)"
+ },
+ "reply_count": {
+ "zero": "0 ответов",
+ "one": "1 ответ",
+ "other": "%(count)s ответа(-ов)"
+ }
+ },
"g": {
"and": "и",
+ "block": "Заблокировать",
+ "blocked": "Заблокирован(-а)",
"blog": "Блог",
"cancel": "Отмена",
"delete": "Удалить",
"dismiss": "Скрыть",
"edit": "Редактировать",
+ "groups": "Группы",
"feed": "Лента",
"incorrect_password": "Неправильный пароль",
"posting_not_memo": "Сейчас нужно ввести posting-ключ. Вы ввели memo.",
"login": "Войти",
"logout": "Выйти",
"mentions": "Упоминания",
+ "modified": " (изменено)",
+ "name": "Имя",
"night_mode": "Ночной режим",
"ok": "OK",
+ "or": "или",
"refresh": "Обновить",
"required": "Обязательно",
"replies": "Ответы",
@@ -195,7 +403,10 @@
"rewards": "Награды",
"settings": "Настройки",
"sign_up": "Регистрация",
+ "submit": "Отправить",
+ "unblock": "Разблокировать",
"username_does_not_exist": "Такого имени не существует",
- "wallet": "Кошелек"
+ "wallet": "Кошелек",
+ "wait": "Ждите..."
}
}
\ No newline at end of file
diff --git a/src/redux/FetchDataSaga.js b/src/redux/FetchDataSaga.js
index 9a947b961..e27de9470 100644
--- a/src/redux/FetchDataSaga.js
+++ b/src/redux/FetchDataSaga.js
@@ -1,13 +1,17 @@
import { call, put, select, fork, cancelled, takeLatest, takeEvery } from 'redux-saga/effects';
-import golos, { api } from 'golos-lib-js'
+import golos, { api, auth } from 'golos-lib-js'
import tt from 'counterpart'
import g from 'app/redux/GlobalReducer'
+import { getSpaceInCache, saveToCache } from 'app/utils/Normalizators'
export function* fetchDataWatches () {
yield fork(watchLocationChange)
yield fork(watchFetchState)
yield fork(watchFetchUiaBalances)
+ yield fork(watchFetchMyGroups)
+ yield fork(watchFetchTopGroups)
+ yield fork(watchFetchGroupMembers)
}
export function* watchLocationChange() {
@@ -18,20 +22,37 @@ export function* watchFetchState() {
yield takeLatest('FETCH_STATE', fetchState)
}
+const setMiniAccount = (state, account) => {
+ if (account) {
+ state.accounts[account.name] = account
+ }
+}
+const addMiniAccounts = (state, accounts) => {
+ if (accounts) {
+ for (const [n, acc] of Object.entries(accounts)) {
+ setMiniAccount(state, acc)
+ }
+ }
+}
+
export function* fetchState(location_change_action) {
try {
-
const { pathname } = location_change_action.payload.location
- const { fake } = location_change_action.payload
+ const { fake, isFirstRendering } = location_change_action.payload
const parts = pathname.split('/')
const state = {}
state.nodeError = null
- state.contacts = [];
- state.messages = [];
- state.messages_update = '0';
- state.accounts = {}
- state.assets = {}
+ state.fetched = ''
+ if (isFirstRendering || fake) {
+ state.contacts = [];
+ state.the_group = undefined
+ state.messages = [];
+ state.messages_update = '0';
+ state.accounts = {}
+ state.assets = {}
+ state.groups = {}
+ }
let hasErr = false
@@ -53,29 +74,118 @@ export function* fetchState(location_change_action) {
const account = yield select(state => state.user.getIn(['current', 'username']));
if (account) {
- accounts.add(account);
+ const posting = yield select(state => state.user.getIn(['current', 'private_keys', 'posting_private']))
- state.contacts = yield callSafe(state, [], 'getContactsAsync', [api, api.getContactsAsync], account, 'unknown', 100, 0)
- if (hasErr) return
+ const path = parts[1]
- if (parts[1]) {
- const to = parts[1].replace('@', '');
- accounts.add(to);
+ const conCache = getSpaceInCache(null, 'contacts')
- state.messages = yield callSafe(state, [], 'getThreadAsync', [api, api.getThreadAsync], account, to, {});
+ if (path.startsWith('@') || !path) {
+ if (window._perfo) console.time('prof: getContactsAsync')
+ const con = yield call([auth, 'withNodeLogin'], { account, keys: { posting },
+ call: async (loginData) => {
+ return await api.getContactsAsync({
+ ...loginData,
+ owner: account, limit: 100,
+ cache: Object.keys(conCache),
+ accounts: true,
+ relations: false,
+ })
+ }
+ })
+ if (window._perfo) console.log('procc:' + con._dec_processed)
+ state.contacts = con.contacts
if (hasErr) return
+ if (window._perfo) console.timeEnd('prof: getContactsAsync')
- if (state.messages.length) {
- state.messages_update = state.messages[state.messages.length - 1].nonce;
- }
+ addMiniAccounts(state, con.accounts)
}
- for (let contact of state.contacts) {
- accounts.add(contact.contact);
+
+ if (path) {
+ if (path.startsWith('@')) {
+ const to = path.replace('@', '');
+
+ const mess = yield callSafe(state, [], 'getThreadAsync', [api, api.getThreadAsync], {
+ from: account,
+ to,
+ accounts: true
+ })
+ if (hasErr) return
+
+ state.messages = mess.messages
+
+ if (state.messages.length) {
+ state.messages_update = state.messages[state.messages.length - 1].nonce;
+ }
+
+ addMiniAccounts(state, mess.accounts)
+ } else {
+ if (window._perfo) console.time('prof: getGroupsAsync')
+ let the_group = yield callSafe(state, [], 'getGroupsAsync', [api, api.getGroupsAsync], {
+ start_group: path,
+ limit: 1,
+ with_members: {
+ accounts: [account]
+ }
+ })
+ if (hasErr) return
+ if (the_group[0] && the_group[0].name === path) {
+ the_group = the_group[0]
+ } else {
+ the_group = null
+ }
+ state.the_group = the_group
+ if (window._perfo) console.timeEnd('prof: getGroupsAsync')
+
+ const space = the_group && getSpaceInCache({ group: the_group.name })
+ if (window._perfo) console.time('prof: getThreadAsync')
+ let query = {
+ group: path,
+ cache: space ? Object.keys(space) : [],
+ accounts: true,
+ contacts: {
+ owner: account, limit: 100,
+ cache: Object.keys(conCache),
+ relations: false,
+ },
+ }
+ const getThread = async (loginData) => {
+ query = {...query, ...loginData}
+ const th = await api.getThreadAsync(query)
+ return th
+ }
+ let thRes
+ if (the_group && the_group.is_encrypted) {
+ thRes = yield call([auth, 'withNodeLogin'], { account, keys: { posting },
+ call: getThread
+ })
+ } else {
+ thRes = yield call(getThread)
+ }
+
+ addMiniAccounts(state, thRes.accounts)
+
+ if (window._perfo) console.log('proc:' + thRes._dec_processed)
+ if (the_group && thRes.error) {
+ the_group.error = thRes.error
+ }
+ state.contacts = thRes.contacts
+ if (thRes.messages) {
+ state.messages = thRes.messages
+ if (state.messages.length) {
+ state.messages_update = state.messages[state.messages.length - 1].nonce;
+ }
+ }
+ if (window._perfo) console.timeEnd('prof: getThreadAsync')
+
+ state.fetched = path
+ }
}
}
if (accounts.size > 0) {
- let accs = yield callSafe(state, [], 'getAccountsAsync', [api, api.getAccountsAsync], Array.from(accounts))
+ let accs = yield callSafe(state, [], 'getAccountsAsync', [api, api.getAccountsAsync], Array.from(accounts),
+ { current: account || '' })
if (hasErr) return
for (let i in accs) {
@@ -109,3 +219,108 @@ export function* fetchUiaBalances({ payload: { account } }) {
console.error('fetchUiaBalances', err)
}
}
+
+export function* watchFetchMyGroups() {
+ yield takeLatest('global/FETCH_MY_GROUPS', fetchMyGroups)
+}
+
+export function* fetchMyGroups({ payload: { account } }) {
+ try {
+ const groupsOwn = yield call([api, api.getGroupsAsync], {
+ member: account,
+ member_types: [],
+ start_group: '',
+ limit: 100,
+ with_members: {
+ accounts: [account]
+ }
+ })
+ let groups = yield call([api, api.getGroupsAsync], {
+ member: account,
+ member_types: ['pending', 'member', 'moder'],
+ start_group: '',
+ limit: 100,
+ with_members: {
+ accounts: [account]
+ }
+ })
+ groups = [...groupsOwn, ...groups]
+ groups.sort((a, b) => {
+ return b.pendings - a.pendings
+ })
+
+ yield put(g.actions.receiveMyGroups({ groups }))
+ } catch (err) {
+ console.error('fetchMyGroups', err)
+ }
+}
+
+export function* watchFetchTopGroups() {
+ yield takeLatest('global/FETCH_TOP_GROUPS', fetchTopGroups)
+}
+
+export function* fetchTopGroups({ payload: { account } }) {
+ try {
+ const groupsWithoutMe = []
+ let start_group = ''
+
+ for (let page = 1; page <= 3; ++page) {
+ if (page > 1) {
+ groupsWithoutMe.pop()
+ }
+
+ const groups = yield call([api, api.getGroupsAsync], {
+ sort: 'by_popularity',
+ start_group,
+ limit: 100,
+ with_members: {
+ accounts: [account]
+ }
+ })
+
+ for (const gro of groups) {
+ start_group = gro.name
+ if ((gro.member_list.length && gro.member_list[0].account == account) || gro.owner == account) {
+ continue
+ }
+ groupsWithoutMe.push(gro)
+ }
+
+ if (groupsWithoutMe.length >= 10 || groups.length < 100) {
+ break
+ }
+ }
+
+ yield put(g.actions.receiveTopGroups({ groups: groupsWithoutMe }))
+ } catch (err) {
+ console.error('fetchTopGroups', err)
+ }
+}
+
+export function* watchFetchGroupMembers() {
+ yield takeLatest('global/FETCH_GROUP_MEMBERS', fetchGroupMembers)
+}
+
+export function* fetchGroupMembers({ payload: { group, creatingNew, memberTypes, sortConditions } }) {
+ try {
+ if (creatingNew) {
+ yield put(g.actions.receiveGroupMembers({ group, members: [], append: true }))
+ return
+ }
+
+ yield put(g.actions.receiveGroupMembers({ group, loading: true }))
+
+ const members = yield call([api, api.getGroupMembersAsync], {
+ group,
+ member_types: memberTypes,
+ sort_conditions: sortConditions,
+ start_member: '',
+ limit: 100,
+ accounts: true,
+ })
+
+ yield put(g.actions.receiveGroupMembers({ group, members }))
+ } catch (err) {
+ console.error('fetchGroupMembers', err)
+ }
+}
\ No newline at end of file
diff --git a/src/redux/GlobalReducer.js b/src/redux/GlobalReducer.js
index e9845952d..3e421ce00 100644
--- a/src/redux/GlobalReducer.js
+++ b/src/redux/GlobalReducer.js
@@ -2,7 +2,34 @@ import { Map, List, fromJS, fromJSGreedy } from 'immutable';
import createModule from 'redux-modules'
import { Asset } from 'golos-lib-js/lib/utils'
-import { processDatedGroup } from 'app/utils/MessageUtils'
+import { session } from 'app/redux/UserSaga'
+import { opGroup } from 'app/utils/groups'
+import { processDatedGroup, opDeleteContact } from 'app/utils/MessageUtils'
+
+const updateInMyGroups = (state, group, groupUpdater, groupsUpserter = mg => mg) => {
+ state = state.update('my_groups', null, mg => {
+ if (!mg) return mg
+ const i = mg.findIndex(gro => gro.get('name') === group)
+ if (i === -1) return groupsUpserter(mg)
+ mg = mg.update(i, (gro) => {
+ if (!gro) return
+
+ return groupUpdater(gro)
+ })
+ return mg
+ })
+ return state
+}
+
+const updateTheGroup = (state, group, groupUpdater) => {
+ state = state.update('the_group', null, (gro) => {
+ if (!gro) return
+ if (gro.get('name') !== group) return gro
+
+ return groupUpdater(gro)
+ })
+ return state
+}
export default createModule({
name: 'global',
@@ -25,17 +52,26 @@ export default createModule({
action: 'RECEIVE_STATE',
reducer: (state, action) => {
let payload = fromJS(action.payload);
- // TODO reserved words used in account names, find correct solution
- /*if (!Map.isMap(payload.get('accounts'))) {
- const accounts = payload.get('accounts');
- payload = payload.set(
- 'accounts',
- fromJSGreedy(accounts)
- );
- }*/
+ payload = payload.update('accounts', accs => {
+ let newMap = Map()
+ accs.forEach((acc, name) => {
+ if (!acc.has('relations')) {
+ acc = acc.set('relations', Map())
+ }
+ if (!acc.hasIn(['relations', 'me_to_them'])) {
+ acc = acc.setIn(['relations', 'me_to_them'], null)
+ }
+ if (!acc.hasIn(['relations', 'they_to_me'])) {
+ acc = acc.setIn(['relations', 'they_to_me'], null)
+ }
+ newMap = newMap.set(name, acc)
+ })
+ return newMap
+ })
let new_state = state.set('messages', List());
new_state = new_state.set('contacts', List());
- return new_state.mergeDeep(payload);
+ new_state = new_state.mergeDeep(payload)
+ return new_state
},
},
{
@@ -48,7 +84,7 @@ export default createModule({
action: 'MESSAGED',
reducer: (
state,
- { payload: { message, timestamp, updateMessage, isMine } }
+ { payload: { message, timestamp, updateMessage, isMine, username } }
) => {
message.create_date = timestamp;
message.receive_date = timestamp;
@@ -57,6 +93,10 @@ export default createModule({
message.donates = '0.000 GOLOS'
message.donates_uia = 0
}
+ const { group, mentions } = opGroup(message)
+ message.group = group
+ message.mentions = mentions
+ message.read_date = (group && !message.to) ? timestamp : '1970-01-01T00:00:00';
let new_state = state;
let messages_update = message.nonce;
@@ -77,25 +117,43 @@ export default createModule({
new_state = new_state.updateIn(['contacts'],
List(),
contacts => {
- let idx = contacts.findIndex(i =>
- i.get('contact') === message.to
- || i.get('contact') === message.from);
+ let idx = contacts.findIndex(i => {
+ if (group) {
+ return i.get('kind') === 'group' && i.get('contact') === group
+ }
+ return i.get('kind') !== 'group' &&
+ (i.get('contact') === message.to
+ || i.get('contact') === message.from)
+ })
+ let newInbox = 0, newMentions = 0
+ if (!isMine && !updateMessage) {
+ if (!group || message.to === username) {
+ newInbox++
+ } else if (group && message.mentions && message.mentions.includes(username)) {
+ newMentions++
+ }
+ }
if (idx === -1) {
- let contact = isMine ? message.to : message.from;
+ let contact = group || (isMine ? message.to : message.from)
contacts = contacts.insert(0, fromJS({
contact,
+ kind: group ? 'group' : 'account',
last_message: message,
size: {
- unread_inbox_messages: !isMine ? 1 : 0,
+ unread_inbox_messages: newInbox,
+ unread_mentions: newMentions,
},
}));
} else {
contacts = contacts.update(idx, contact => {
contact = contact.set('last_message', fromJS(message));
- if (!isMine && !updateMessage) {
- let msgs = contact.getIn(['size', 'unread_inbox_messages']);
- contact = contact.setIn(['size', 'unread_inbox_messages'],
- msgs + 1);
+ if (newInbox) {
+ contact = contact.updateIn(['size', 'unread_inbox_messages'],
+ msgs => msgs + newInbox)
+ }
+ if (newMentions) {
+ contact = contact.updateIn(['size', 'unread_mentions'],
+ msgs => msgs + newMentions)
}
return contact
});
@@ -107,6 +165,15 @@ export default createModule({
});
return contacts;
});
+ let { from_account } = message
+ if (from_account && from_account.name) {
+ from_account = fromJS(from_account)
+ new_state = new_state.updateIn(
+ ['accounts', from_account.get('name')],
+ Map(),
+ a => a.mergeDeep(from_account)
+ )
+ }
return new_state;
},
},
@@ -146,12 +213,14 @@ export default createModule({
) => {
let new_state = state;
let messages_update = message.nonce || Math.random();
+ const { group, requester } = opGroup(message)
if (updateMessage) {
new_state = new_state.updateIn(['messages'],
List(),
messages => {
return processDatedGroup(message, messages, (msg, idx) => {
- return msg.set('read_date', timestamp);
+ msg = msg.set('read_date', timestamp)
+ return { updated: msg }
});
});
}
@@ -159,7 +228,7 @@ export default createModule({
List(),
contacts => {
let idx = contacts.findIndex(i =>
- i.get('contact') === (isMine ? message.to : message.from));
+ i.get('contact') === (group || (isMine ? message.to : message.from)))
if (idx !== -1) {
contacts = contacts.update(idx, contact => {
// to update read_date (need for isMine case), and more actualize text
@@ -173,6 +242,9 @@ export default createModule({
// currently used only !isMine case
const msgsKey = isMine ? 'unread_outbox_messages' : 'unread_inbox_messages';
contact = contact.setIn(['size', msgsKey], 0);
+ if (!isMine) {
+ contact = contact.setIn(['size', 'unread_mentions'], 0)
+ }
return contact;
});
}
@@ -190,15 +262,39 @@ export default createModule({
) => {
let new_state = state;
if (updateMessage) {
- new_state = new_state.updateIn(['messages'],
- List(),
- messages => {
- const idx = messages.findIndex(i => i.get('nonce') === message.nonce);
- if (idx !== -1) {
- messages = messages.delete(idx);
- }
- return messages;
- });
+ if (message.nonce) {
+ new_state = new_state.updateIn(['messages'],
+ List(),
+ messages => {
+ const idx = messages.findIndex(i => i.get('nonce') === message.nonce);
+ if (idx !== -1) {
+ messages = messages.delete(idx);
+ }
+ return messages;
+ })
+ } else {
+ new_state = new_state.updateIn(['messages'],
+ List(),
+ messages => {
+ return processDatedGroup(message, messages, (msg, idx) => {
+ return { updated: null, fixIdx: idx - 1 }
+ });
+ })
+ }
+ }
+ const delCon = opDeleteContact(message)
+ if (delCon) {
+ new_state = new_state.updateIn(['contacts'],
+ List(),
+ contacts => {
+ let idx = contacts.findIndex(i =>
+ i.get('contact') === message.to
+ || i.get('contact') === message.from)
+ if (idx !== -1) {
+ contacts = contacts.delete(idx)
+ }
+ return contacts
+ })
}
return new_state;
},
@@ -264,5 +360,220 @@ export default createModule({
return state.set('assets', fromJS(assets))
},
},
+ {
+ action: 'FETCH_MY_GROUPS',
+ reducer: state => state
+ },
+ {
+ action: 'RECEIVE_MY_GROUPS',
+ reducer: (state, { payload: { groups } }) => {
+ return state.set('my_groups', fromJS(groups))
+ },
+ },
+ {
+ action: 'FETCH_TOP_GROUPS',
+ reducer: state => state
+ },
+ {
+ action: 'RECEIVE_TOP_GROUPS',
+ reducer: (state, { payload: { groups } }) => {
+ return state.set('top_groups', fromJS(groups))
+ },
+ },
+ {
+ action: 'FETCH_GROUP_MEMBERS',
+ reducer: state => state
+ },
+ {
+ action: 'RECEIVE_GROUP_MEMBERS',
+ reducer: (state, { payload: { group, members, loading, append } }) => {
+ let new_state = state
+ new_state = state.updateIn(['groups', group],
+ Map(),
+ gro => {
+ gro = gro.updateIn(['members'], Map(), mems => {
+ mems = mems.set('loading', loading || false)
+ if (append) {
+ // Immutable's: update do not wants to add notSet, if array is empty...
+ if (!mems.has('data')) {
+ mems = mems.set('data', List())
+ }
+ mems = mems.update('data', List(), data => {
+ for (const item of (members || [])) {
+ data = data.push(fromJS(item))
+ }
+ return data
+ })
+ } else {
+ mems = mems.set('data', fromJS(members || []))
+ }
+ return mems
+ })
+ return gro
+ })
+ for (const mem of (members || [])) {
+ if (mem.account_data) {
+ const account = fromJS(mem.account_data)
+ new_state = new_state.updateIn(
+ ['accounts', account.get('name')],
+ Map(),
+ a => a.mergeDeep(account)
+ )
+ }
+ }
+ return new_state
+ },
+ },
+ {
+ action: 'UPSERT_GROUP',
+ reducer: (state, { payload }) => {
+ const { creator, name, is_encrypted, privacy, json_metadata } = payload
+ let new_state = state
+ const groupUpdater = gro => {
+ gro = gro.set('json_metadata', json_metadata)
+ gro = gro.set('privacy', privacy)
+ return gro
+ }
+ const groupsUpserter = myGroups => {
+ const now = new Date().toISOString().split('.')[0]
+ myGroups = myGroups.insert(0, fromJS({
+ owner: creator,
+ name,
+ json_metadata,
+ is_encrypted,
+ privacy,
+ created: now,
+ admins: 0,
+ moders: 0,
+ members: 0,
+ pendings: 0,
+ banneds: 0,
+ member_list: []
+ }))
+ return myGroups
+ }
+ new_state = updateInMyGroups(new_state, name, groupUpdater, groupsUpserter)
+ new_state = updateTheGroup(new_state, name, groupUpdater)
+ return new_state
+ }
+ },
+ {
+ action: 'UPDATE_GROUP_MEMBER',
+ reducer: (state, { payload: { group, member, member_type } }) => {
+ const now = new Date().toISOString().split('.')[0]
+ let new_state = state
+ let oldType
+ new_state = state.updateIn(['groups', group],
+ Map(),
+ gro => {
+ gro = gro.updateIn(['members', 'data'], List(), mems => {
+ const retiring = member_type === 'retired'
+ const idx = mems.findIndex(i => i.get('account') === member)
+ if (idx !== -1) {
+ oldType = mems.get(idx).get('member_type')
+ if (retiring) {
+ mems = mems.remove(idx)
+ } else {
+ mems = mems.update(idx, mem => {
+ mem = mem.set('member_type', member_type)
+ return mem
+ })
+ }
+ } else if (!retiring) {
+ mems = mems.insert(0, fromJS({
+ group,
+ account: member,
+ json_metadata: '{}',
+ member_type,
+ invited: member,
+ joined: now,
+ updated: now,
+ }))
+ }
+ return mems
+ })
+ return gro
+ })
+ const groupUpdater = gro => {
+ if (!gro.has('member_list')) {
+ gro = gro.set('member_list', List())
+ }
+ gro = gro.update('member_list', List(), data => {
+ let newList = List()
+ let found
+ data.forEach((mem, i) => {
+ if (mem.get('account') === member) {
+ found = true
+ if (!oldType) oldType = mem.get('member_type')
+ if (member_type !== 'retired') {
+ const newMem = mem.set('member_type', member_type)
+ newList = newList.push(newMem)
+ }
+ } else {
+ newList = newList.push(mem)
+ }
+ })
+ if (!found) {
+ newList = newList.push(fromJS({
+ account: member,
+ member_type,
+ }))
+ }
+ return newList
+ })
+
+ const updateByType = (t, updater) => {
+ if (t === 'member') {
+ gro = gro.update('members', updater)
+ } else if (t === 'moder') {
+ gro = gro.update('moders', updater)
+ } else if (t === 'pending') {
+ gro = gro.update('pendings', updater)
+ } else if (t === 'banned') {
+ gro = gro.update('banneds', updater)
+ }
+ }
+ updateByType(oldType, n => --n)
+ updateByType(member_type, n => ++n)
+
+ return gro
+ }
+ new_state = updateInMyGroups(new_state, group, groupUpdater)
+ new_state = updateTheGroup(new_state, group, groupUpdater)
+ new_state = new_state.updateIn(['accounts', member],
+ Map(),
+ acc => {
+ acc = acc.set('member_type', member_type)
+ return acc
+ })
+ return new_state
+ },
+ },
+ {
+ action: 'UPDATE_BLOCKING',
+ reducer: (state, { payload: { blocker, blocking, block } }) => {
+ let username
+ const sess = session.load()
+ if (sess) username = sess[0]
+ const account = blocker === username ? blocking : blocker
+
+ let new_state = state.updateIn(['accounts', account],
+ Map(),
+ acc => {
+ if (!acc.has('relations')) {
+ acc = acc.set('relations', Map())
+ }
+ const path = ['relations', blocker === username ? 'me_to_them' : 'they_to_me']
+ if (block) {
+ acc = acc.setIn(path, 'blocking')
+ } else {
+ acc = acc.deleteIn(path)
+ }
+ return acc
+ })
+
+ return new_state
+ },
+ },
],
})
diff --git a/src/redux/PollDataSaga.js b/src/redux/PollDataSaga.js
index 379d9dcba..bc087cde0 100644
--- a/src/redux/PollDataSaga.js
+++ b/src/redux/PollDataSaga.js
@@ -11,6 +11,10 @@ const wait = ms => (
let webpush_params = null;
export default function* pollData() {
+ if (process.env.NO_NOTIFY) { // config-overrides.js, yarn run dev
+ console.warn('Notifications disabled in environment variables')
+ return
+ }
while(true) {
if (document.visibilityState !== 'hidden') {
const username = yield select(state => state.user.getIn(['current', 'username']));
diff --git a/src/redux/TransactionSaga.js b/src/redux/TransactionSaga.js
index 63ae9c7e4..5c4ccc8ac 100644
--- a/src/redux/TransactionSaga.js
+++ b/src/redux/TransactionSaga.js
@@ -4,6 +4,8 @@ import golos from 'golos-lib-js'
import g from 'app/redux/GlobalReducer'
import user from 'app/redux/UserReducer'
+import { messageOpToObject } from 'app/utils/Normalizators'
+import { translateError } from 'app/utils/translateError'
export function* transactionWatches() {
yield fork(watchForBroadcast)
@@ -15,8 +17,23 @@ export function* watchForBroadcast() {
const hook = {
preBroadcast_custom_json,
+ accepted_custom_json,
}
+function* accepted_custom_json({operation}) {
+ const json = JSON.parse(operation.json)
+ if (operation.id === 'private_message') {
+ if (json[0] === 'private_group') {
+ yield put(g.actions.upsertGroup(json[1]))
+ } else if (json[0] === 'private_group_member') {
+ const { name, member, member_type } = json[1]
+ yield put(g.actions.updateGroupMember({ group: name, member, member_type, }))
+ }
+ }
+ return operation
+}
+
+
function* preBroadcast_custom_json({operation}) {
const json = JSON.parse(operation.json)
if (operation.id === 'private_message') {
@@ -28,17 +45,19 @@ function* preBroadcast_custom_json({operation}) {
updater: msgs => {
const idx = msgs.findIndex(i => i.get('nonce') === json[1].nonce);
if (idx === -1) {
- msgs = msgs.insert(0, fromJS({
- nonce: json[1].nonce,
- checksum: json[1].checksum,
- from: json[1].from,
- read_date: '1970-01-01T00:00:00',
- create_date: new Date().toISOString().split('.')[0],
- receive_date: '1970-01-01T00:00:00',
- encrypted_message: json[1].encrypted_message,
- donates: '0.000 GOLOS',
- donates_uia: 0
- }))
+ let group = ''
+ let mentions = []
+ const exts = json[1].extensions || []
+ for (const [key, val ] of exts) {
+ if (key === 0) {
+ group = val.group
+ mentions = val.mentions
+ break
+ }
+ }
+ const newMsg = messageOpToObject(json[1], group, mentions)
+ msgs = msgs.insert(0, fromJS(newMsg))
+ messages_update = json[1].nonce;
} else {
messages_update = json[1].nonce;
msgs = msgs.update(idx, msg => {
@@ -114,9 +133,15 @@ function* broadcastOperation(
return;
}
- const posting_private = yield select(state => state.user.getIn(['current', 'private_keys', 'posting_private']));
- if (!posting_private) {
- alert('Not authorized')
+ if (!keys) keys = ['posting']
+ keys = [...new Set(keys)] // remove duplicate
+ const idxP = keys.indexOf('posting')
+ if (idxP !== -1) {
+ const posting = yield select(state => state.user.getIn(['current', 'private_keys', 'posting_private']));
+ if (!posting) {
+ alert('Not authorized')
+ }
+ keys[idxP] = posting
}
let operations = trx || [
@@ -144,11 +169,23 @@ function* broadcastOperation(
}
try {
const res = yield golos.broadcast.sendAsync(
- tx, [posting_private])
+ tx, keys)
+ for (const [type, operation] of operations) {
+ if (hook['accepted_' + type]) {
+ try {
+ yield call(hook['accepted_' + type], {operation})
+ } catch (error) {
+ console.error(error)
+ }
+ }
+ }
} catch (err) {
console.error('Broadcast error', err)
if (errorCallback) {
- errorCallback(err)
+ let errStr = err.toString()
+ errStr = translateError(errStr, err.payload)
+ errStr = errStr.substring(0, 160)
+ errorCallback(err, errStr)
}
return
}
diff --git a/src/redux/UserReducer.js b/src/redux/UserReducer.js
index 20fe4bfd1..691307dd3 100644
--- a/src/redux/UserReducer.js
+++ b/src/redux/UserReducer.js
@@ -5,6 +5,11 @@ const defaultState = fromJS({
current: null,
show_login_modal: false,
show_donate_modal: false,
+ show_create_group_modal: false,
+ show_my_groups_modal: false,
+ show_top_groups_modal: false,
+ show_group_settings_modal: false,
+ show_group_members_modal: false,
show_app_download_modal: false,
loginLoading: false,
pub_keys_used: null,
@@ -128,6 +133,31 @@ export default createModule({
{ action: 'HIDE_CONNECTION_ERROR_MODAL', reducer: state => state.set('hide_connection_error_modal', true) },
{ action: 'SHOW_DONATE', reducer: state => state.set('show_donate_modal', true) },
{ action: 'HIDE_DONATE', reducer: state => state.set('show_donate_modal', false) },
+ { action: 'SHOW_CREATE_GROUP', reducer: (state, { payload: { redirectAfter }}) => {
+ state = state.set('show_create_group_modal', true)
+ state = state.set('create_group_redirect_after', redirectAfter)
+ return state
+ }},
+ { action: 'HIDE_CREATE_GROUP', reducer: state => state.set('show_create_group_modal', false) },
+ { action: 'SHOW_MY_GROUPS', reducer: state => state.set('show_my_groups_modal', true) },
+ { action: 'HIDE_MY_GROUPS', reducer: state => state.set('show_my_groups_modal', false) },
+ { action: 'SHOW_TOP_GROUPS', reducer: state => state.set('show_top_groups_modal', true) },
+ { action: 'HIDE_TOP_GROUPS', reducer: state => state.set('show_top_groups_modal', false) },
+ { action: 'SHOW_GROUP_SETTINGS', reducer: (state, { payload: { group }}) => {
+ state = state.set('show_group_settings_modal', true)
+ state = state.set('current_group', fromJS(group))
+ return state
+ }},
+ { action: 'HIDE_GROUP_SETTINGS', reducer: state => state.set('show_group_settings_modal', false) },
+ { action: 'SHOW_GROUP_MEMBERS', reducer: (state, { payload: { group, show_pendings }}) => {
+ state = state.set('show_group_members_modal', true)
+ state = state.set('group_members_modal', fromJS({
+ group,
+ show_pendings,
+ }))
+ return state
+ }},
+ { action: 'HIDE_GROUP_MEMBERS', reducer: state => state.set('show_group_members_modal', false) },
{ action: 'SHOW_APP_DOWNLOAD', reducer: state => state.set('show_app_download_modal', true) },
{ action: 'HIDE_APP_DOWNLOAD', reducer: state => state.set('show_app_download_modal', false) },
{ action: 'SET_DONATE_DEFAULTS', reducer: (state, {payload}) => state.set('donate_defaults', fromJS(payload)) },
diff --git a/src/redux/UserSaga.js b/src/redux/UserSaga.js
index fc3c054e5..b2fa49b8f 100644
--- a/src/redux/UserSaga.js
+++ b/src/redux/UserSaga.js
@@ -1,7 +1,7 @@
import { Map, fromJS } from 'immutable'
import { call, put, select, fork, takeLatest, takeEvery } from 'redux-saga/effects'
import { auth, api, config } from 'golos-lib-js'
-import { Session, signData } from 'golos-lib-js/lib/auth'
+import { Session, PageSession, signData } from 'golos-lib-js/lib/auth'
import { PrivateKey, Signature, hash } from 'golos-lib-js/lib/auth/ecc'
import g from 'app/redux/GlobalReducer'
@@ -11,7 +11,8 @@ import uploadImageWatch from 'app/redux/UserSaga_UploadImage'
import { authApiLogin, authApiLogout } from 'app/utils/AuthApiClient'
import { notifyApiLogin, notifyApiLogout, notificationUnsubscribe } from 'app/utils/NotifyApiClient'
-const session = new Session('msgr_auth')
+export const session = new Session('msgr_auth')
+export const pageSession = new PageSession('msgr_auth')
export function* userWatches() {
yield fork(loginWatch)
@@ -133,10 +134,15 @@ function* usernamePasswordLogin(action) {
yield put(user.actions.setUser({ username, private_keys, }))
}
+ const { errorLogs } = window
+
if (postingWif) {
let alreadyAuthorized = false;
try {
const res = yield notifyApiLogin(username, localStorage.getItem('X-Auth-Session'));
+
+ errorLogs.push({ details: { notifyApiLogin1: res } })
+
alreadyAuthorized = (res.status === 'ok');
} catch(error) {
// Does not need to be fatal
@@ -147,6 +153,9 @@ function* usernamePasswordLogin(action) {
let authorized = false;
try {
const res = yield authApiLogin(username, null);
+
+ errorLogs.push({ details: { authApiLogin1: res } })
+
if (!res.already_authorized) {
console.log('login_challenge', res.login_challenge);
@@ -155,6 +164,9 @@ function* usernamePasswordLogin(action) {
posting: postingWif,
});
const res2 = yield authApiLogin(username, signatures);
+
+ errorLogs.push({ details: { authApiLogin2: res2 } })
+
if (res2.guid) {
localStorage.setItem('guid', res2.guid)
}
@@ -173,6 +185,8 @@ function* usernamePasswordLogin(action) {
try {
const res = yield notifyApiLogin(username, localStorage.getItem('X-Auth-Session'));
+ errorLogs.push({ details: { notifyApiLogin2: res } })
+
if (res.status !== 'ok') {
throw new Error(res);
}
@@ -244,7 +258,6 @@ function* getAccountHandler({ payload: { usernames, resolve, reject }}) {
}
const accounts = yield call([api, api.getAccountsAsync], usernames)
-
for (let account of accounts) {
yield put(g.actions.receiveAccount({ account }))
}
diff --git a/src/utils/MessageUtils.js b/src/utils/MessageUtils.js
index 144a89bf6..f69da6d14 100644
--- a/src/utils/MessageUtils.js
+++ b/src/utils/MessageUtils.js
@@ -6,12 +6,20 @@ export function displayQuoteMsg(body) {
}
export function processDatedGroup(group, messages, for_each) {
+ let deleteIt
if (group.nonce) {
const idx = messages.findIndex(i => i.get('nonce') === group.nonce);
if (idx !== -1) {
messages = messages.update(idx, (msg) => {
- return for_each(msg, idx);
- });
+ const { updated, fixIdx } = for_each(msg, idx)
+ if (!updated) {
+ deleteIt = idx
+ }
+ return updated || msg
+ })
+ if (deleteIt !== undefined) {
+ messages = messages.delete(idx)
+ }
}
} else {
let inRange = false;
@@ -26,9 +34,36 @@ export function processDatedGroup(group, messages, for_each) {
break;
}
if (inRange) {
- messages = messages.set(idx, for_each(msg, idx));
+ deleteIt = undefined
+ messages = messages.update(idx, (msg) => {
+ const { updated, fixIdx } = for_each(msg, idx)
+ if (!updated) {
+ deleteIt = idx
+ }
+ if (fixIdx !== undefined) {
+ idx = fixIdx
+ }
+ return updated || msg
+ })
+ if (deleteIt !== undefined) {
+ messages = messages.delete(idx)
+ }
}
}
}
return messages;
}
+
+export function opDeleteContact(op) {
+ let delete_contact
+ if (!op) return delete_contact
+ const { extensions } = op
+ if (extensions) {
+ for (const ext of extensions) {
+ if (ext && ext[0] === 1) {
+ delete_contact = ext[1] && ext[1].delete_contact
+ }
+ }
+ }
+ return delete_contact
+}
diff --git a/src/utils/Normalizators.js b/src/utils/Normalizators.js
index 9200d4da5..8c9eea862 100644
--- a/src/utils/Normalizators.js
+++ b/src/utils/Normalizators.js
@@ -1,20 +1,122 @@
import golos from 'golos-lib-js'
import tt from 'counterpart'
+import { getGroupLogo } from 'app/utils/groups'
import { getProfileImage } from 'app/utils/NormalizeProfile';
-function getProfileImageLazy(account, cachedProfileImages) {
- if (!account)
- return getProfileImage(null);
- let cached = cachedProfileImages[account.name];
- if (cached)
- return cached;
- const image = getProfileImage(account);
- cachedProfileImages[account.name] = image;
+const { decodeMsgs } = golos.messages
+
+function getProfileImageLazy(contact, account, cachedProfileImages) {
+ if (!contact || !contact.contact)
+ return getProfileImage(null)
+ const now = Date.now()
+ let cached = cachedProfileImages[contact.contact];
+ if (cached && now - cached.time < 60*1000)
+ return cached.image
+ //console.log('getProfileImageLazy', contact.contact)
+ const image = contact.kind === 'group' ?
+ getGroupLogo(contact.object_meta) : getProfileImage(account)
+ cachedProfileImages[contact.contact] = { image, time: now }
return image;
}
-export function normalizeContacts(contacts, accounts, currentUser, preDecoded, cachedProfileImages) {
+const getCache = () => {
+ if (!window.preDecoded) window.preDecoded = {}
+ return window.preDecoded
+}
+
+export const getSpaceInCache = (msg, spaceKey = '') => {
+ const preDecoded = getCache()
+ const key = spaceKey || (msg.group ? msg.group : '')
+ if (!preDecoded[key]) preDecoded[key] = {}
+ const space = preDecoded[key]
+ return space
+}
+
+export const getContactsSpace = (msg) => {
+ return getSpaceInCache(msg, 'contacts')
+}
+
+const zeroDate = '1970-01-01T00:00:00'
+
+const cacheKey = (msg) => {
+ let key = [msg.nonce]
+ let recDate = msg.receive_date
+ if (recDate === msg.create_date) {
+ recDate = zeroDate
+ }
+ if (msg.group) {
+ key.push(recDate)
+ key.push(msg.from)
+ key.push(msg.to)
+ } else {
+ key.push(recDate)
+ }
+ key = key.join('|')
+ return key
+}
+
+export const saveToCache = (msg, contact = false, general = true) => {
+ if (!msg.message) return false
+ if (msg.group && msg.decrypt_date !== msg.receive_date) return false
+ const key = cacheKey(msg)
+ if (general) {
+ const space = getSpaceInCache(msg)
+ space[key] = { message: msg.message }
+ }
+ if (contact) {
+ const cont = getContactsSpace(msg)
+ cont[key] = { message: msg.message }
+ }
+ return true
+}
+
+const loadFromCache = (msg, contact = false) => {
+ const space = getSpaceInCache(msg)
+ const key = cacheKey(msg)
+ const pd = space[key]
+ if (pd) {
+ msg.message = pd.message
+ return true
+ }
+ if (contact) {
+ const cont = getContactsSpace(msg)
+ const pdc = cont[key]
+ if (pdc) {
+ msg.message = pdc.message
+ return true
+ }
+ }
+ return false
+}
+
+export function messageOpToObject(op, group, mentions = []) {
+ const obj = {
+ nonce: op.nonce,
+ checksum: op.checksum,
+ from: op.from,
+ from_memo_key: op.from_memo_key,
+ to_memo_key: op.to_memo_key,
+ group,
+ read_date: zeroDate,
+ create_date: new Date().toISOString().split('.')[0],
+ receive_date: zeroDate,
+ encrypted_message: op.encrypted_message,
+ donates: '0.000 GOLOS',
+ donates_uia: 0,
+ mentions,
+ }
+ return obj
+}
+
+export function cacheMyOwnMsg(op, group, message) {
+ const newMsg = messageOpToObject(op, group ? group.name : '')
+ newMsg.message = message
+ newMsg.decrypt_date = newMsg.receive_date
+ saveToCache(newMsg, true)
+}
+
+export async function normalizeContacts(contacts, accounts, currentUser, cachedProfileImages) {
if (!currentUser || !accounts)
return [];
@@ -22,53 +124,77 @@ export function normalizeContacts(contacts, accounts, currentUser, preDecoded, c
if (!currentAcc)
return [];
- const private_key = currentUser.getIn(['private_keys', 'memo_private']);
+ const posting = currentUser.getIn(['private_keys', 'posting_private'])
+ const private_memo = currentUser.getIn(['private_keys', 'memo_private']);
const tt_invalid_message = tt('messages.invalid_message');
let contactsCopy = contacts ? [...contacts.toJS()] : [];
+ let messages = []
for (let contact of contactsCopy) {
let account = accounts && accounts[contact.contact];
- contact.avatar = getProfileImageLazy(account, cachedProfileImages);
+
+ const isGroup = contact.kind === 'group'
+ const { url, isDefault } = getProfileImageLazy(contact,
+ account,
+ cachedProfileImages)
+ if (!isDefault || isGroup) {
+ contact.avatar = url
+ }
if (contact.last_message.create_date.startsWith('1970')) {
contact.last_message.message = { body: '', };
continue;
}
- let public_key;
- if (currentAcc.memo_key === contact.last_message.to_memo_key) {
- public_key = contact.last_message.from_memo_key;
- } else {
- public_key = contact.last_message.to_memo_key;
- }
+ messages.push(contact.last_message)
+ }
- try {
- golos.messages.decode(private_key, public_key, [contact.last_message],
- (msg, idx, results) => {
+ try {
+ await decodeMsgs({ msgs: messages, private_memo,
+ login: {
+ account: currentAcc.name, keys: { posting },
+ },
+ before_decode: (msg, idx, results) => {
+ if (!msg.isGroup) {
if (msg.read_date.startsWith('19') && msg.from === currentAcc.name) {
msg.unread = true;
}
- let pd = preDecoded[msg.nonce + '' + msg.receive_date];
- if (pd) {
- msg.message = pd;
- return true;
- }
- return false;
- }, (msg) => {
- preDecoded[msg.nonce + '' + msg.receive_date] = msg.message;
- }, (msg, idx, exception) => {
- msg.message = { body: tt_invalid_message, invalid: true, };
- }, 0, 1);
- } catch (ex) {
- console.log(ex);
- }
+ }
+
+ if (window._perfo) console.log('FCC1')
+ if (loadFromCache(msg, true)) {
+ return true
+ }
+ if (window._perfo) console.log('FCC2')
+ return false;
+ },
+ for_each: (msg) => {
+ saveToCache(msg, true)
+ },
+ on_error: (msg, idx, exception) => {
+ console.error(exception)
+ msg.message = { body: tt_invalid_message, invalid: true, };
+ saveToCache(msg, true, false)
+ },
+ begin_idx: 0,
+ end_idx: messages.length,
+ })
+ } catch (ex) {
+ console.log(ex);
}
+
return contactsCopy
}
-export function normalizeMessages(messages, accounts, currentUser, to, preDecoded) {
- if (!to || !accounts[to]) {
+export async function normalizeMessages(messages, accounts, currentUser, to) {
+ let isGroup = false
+ if (to) {
+ if (to[0] !== '@') isGroup = true
+ to = to.replace('@', '')
+ }
+
+ if (!to || (!isGroup && !accounts[to])) {
return [];
}
@@ -76,46 +202,64 @@ export function normalizeMessages(messages, accounts, currentUser, to, preDecode
let id = 0;
try {
- const private_key = currentUser.getIn(['private_keys', 'memo_private']);
-
let currentAcc = accounts[currentUser.get('username')];
const tt_invalid_message = tt('messages.invalid_message');
- let messagesCopy2 = golos.messages.decode(private_key, accounts[to].memo_key, messagesCopy,
- (msg, i, results) => {
+ const posting = currentUser.getIn(['private_keys', 'posting_private'])
+ const privateMemo = currentUser.getIn(['private_keys', 'memo_private']);
+
+ if (window._perfo) console.log('ttt', Date.now())
+ const decoded = await decodeMsgs({ msgs: messagesCopy,
+ private_memo: !isGroup && privateMemo,
+ login: {
+ account: currentAcc.name, keys: { posting },
+ },
+ before_decode: (msg, i, results) => {
msg.id = ++id;
msg.author = msg.from;
msg.date = new Date(msg.create_date + 'Z');
- if (msg.to === currentAcc.name) {
- if (msg.read_date.startsWith('19')) {
- msg.toMark = true;
- }
- } else {
- if (msg.read_date.startsWith('19')) {
- msg.unread = true;
+ if (msg.read_date.startsWith('19')) {
+ if (!isGroup) {
+ if (msg.to === currentAcc.name) {
+ msg.toMark = true
+ } else {
+ msg.unread = true
+ }
+ } else {
+ if (msg.to === currentAcc.name) {
+ msg.toMark = true
+ } else if (msg.to) {
+ msg.unread = true
+ }
+ if (!msg.toMark && msg.mentions.includes(currentAcc.name)) {
+ msg.toMark = true
+ }
}
}
+ //msg.decrypt_date = null
- let pd = preDecoded[msg.nonce + '' + msg.receive_date];
- if (pd) {
- msg.message = pd;
- results.push(msg);
- return true;
+ if (window._perfo) console.log('FC1')
+ if (loadFromCache(msg)) {
+ results.push(msg)
+ return true
}
+ if (window._perfo) console.log('FC2')
return false;
},
- (msg) => {
- preDecoded[msg.nonce + '' + msg.receive_date] = msg.message;
+ for_each: (msg, i) => {
+ saveToCache(msg)
},
- (msg, i, err) => {
- console.log(err);
- msg.message = {body: tt_invalid_message, invalid: true};
+ on_error: (msg, i, err) => {
+ console.error(err, msg)
+ msg.message = {body: tt_invalid_message, invalid: true}
},
- messagesCopy.length - 1, -1);
-
- return messagesCopy2;
+ begin_idx: messagesCopy.length - 1,
+ end_idx: -1,
+ })
+ if (window._perfo) console.log('ttte', Date.now())
+ return decoded
} catch (ex) {
console.log(ex);
return [];
diff --git a/src/utils/NormalizeProfile.js b/src/utils/NormalizeProfile.js
index a3c0f3ad4..e2f5dbfad 100644
--- a/src/utils/NormalizeProfile.js
+++ b/src/utils/NormalizeProfile.js
@@ -14,14 +14,14 @@ export function getProfileImage(account, size = 48) {
if (url && /^(https?:)\/\//.test(url)) {
size = size > 75 ? '200x200' : '75x75';
url = proxifyImageUrl(url, size);
- return url;
+ return { url }
}
}
} catch (e) {
console.error(e);
}
}
- return require('app/assets/images/user.png');
+ return { url: require('app/assets/images/user.png'), isDefault: true }
}
/**
@@ -32,6 +32,6 @@ export function getLastSeen(account) {
account.last_bandwidth_update, // all operations
account.created,
];
- const last = max(dates);
- return last.startsWith('19') ? null : last;
+ const last = account.last_seen || max(dates);
+ return (!last || last.startsWith('19')) ? null : last;
}
diff --git a/src/utils/NotifyApiClient.js b/src/utils/NotifyApiClient.js
index 58068c580..602892e90 100644
--- a/src/utils/NotifyApiClient.js
+++ b/src/utils/NotifyApiClient.js
@@ -14,12 +14,20 @@ const notifyAvailable = () => {
&& $GLS_Config.notify_service && $GLS_Config.notify_service.host;
};
-const notifyUrl = (pathname) => {
+export function notifyWsHost() {
+ return notifyAvailable() && $GLS_Config.notify_service.host_ws
+}
+
+export function notifyUrl(pathname = '') {
return new URL(pathname, window.$GLS_Config.notify_service.host).toString();
-};
+}
+
+function notifySession() {
+ return localStorage.getItem('X-Session')
+}
function setSession(request) {
- request.headers['X-Session'] = localStorage.getItem('X-Session');
+ request.headers['X-Session'] = notifySession()
}
function saveSession(response) {
@@ -34,6 +42,103 @@ function saveSession(response) {
localStorage.setItem('X-Session', session);
}
+
+async function connectNotifyWs() {
+ if (!window.notifyWs || window.notifyWs.readyState !== 1) {
+ window.notifyWsReq = { id: 0, requests: {}, callbacks: {} }
+ if (window.notifyWs) {
+ window.notifyWs.close()
+ }
+ await new Promise((resolve, reject) => {
+ const notifyWs = new WebSocket(notifyWsHost())
+ window.notifyWs = notifyWs
+
+ const timeout = setTimeout(() => {
+ if (notifyWs && !notifyWs.isOpen) {
+ reject(new Error('Cannot connect Notify WS'))
+ }
+ }, 5000)
+
+ notifyWs.addEventListener('open', () => {
+ notifyWs.isOpen = true
+ clearTimeout(timeout)
+ resolve()
+ })
+
+ notifyWs.addEventListener('сlose', () => {
+ if (!notifyWs.isOpen) {
+ clearTimeout(timeout)
+ const err = new Error('notifyWs - cannot connect')
+ reject(err)
+ } else {
+ console.log('NOTW close')
+ }
+ })
+
+ notifyWs.addEventListener('message', (msg) => {
+ if (window._notifyDebug) {
+ console.log('notifyWs message:', msg)
+ }
+ const data = JSON.parse(msg.data)
+ const id = data.id
+ const request = window.notifyWsReq.requests[id]
+ if (request) {
+ const cleanRequest = () => {
+ delete window.notifyWsReq.requests[id]
+ }
+
+ if (data.err) {
+ request.callback(new Error(data.err.code + ': ' + data.err.msg), data)
+ cleanRequest()
+ return
+ }
+ request.callback(null, data.data)
+ cleanRequest()
+ } else if (!id && data.data && data.data.event) {
+ const { event } = data.data
+ const callback = window.notifyWsReq.callbacks[event]
+ if (callback) {
+ callback.callback(null, data.data)
+ }
+ }
+ })
+ })
+ }
+}
+
+async function notifyWsSend(api, args, callback = null, eventCallback = null) {
+ try {
+ await connectNotifyWs()
+ const id = window.notifyWsReq.id++
+ let msg = {
+ api,
+ args,
+ id
+ }
+ msg = JSON.stringify(msg)
+ if (callback) {
+ window.notifyWsReq.requests[id] = { callback }
+ }
+ if (eventCallback) {
+ const { event, callback } = eventCallback
+ window.notifyWsReq.callbacks[event] = { callback }
+ }
+ window.notifyWs.send(msg)
+ } catch (err) {
+ if (callback) {
+ callback(err, null)
+ }
+ }
+}
+
+export async function notifyWsPing() {
+ await connectNotifyWs()
+ if (!window.notifyWs || window.notifyWs.readyState !== 1) {
+ throw new Error('Ping detected what Notify WS not ready')
+ }
+ window.notifyWs.send(JSON.stringify({ ping: 1 }))
+}
+
export function notifyApiLogin(account, authSession) {
if (!notifyAvailable()) return;
let request = Object.assign({}, request_base, {
@@ -105,6 +210,25 @@ export async function notificationSubscribe(account, scopes = 'message,donate_ms
throw new Error('Cannot subscribe');
}
+export async function notificationSubscribeWs(account, callback, scopes = 'message,donate_msgs', sidKey = '__subscriber_id') {
+ if (!notifyWsHost()) throw new Error('No notify_service host_ws in config')
+ const xSession = notifySession()
+ return await new Promise(async (resolve, reject) => {
+ await notifyWsSend('queues/subscribe', {
+ account,
+ 'X-Session': xSession,
+ scopes,
+ }, (err, res) => {
+ if (err) {
+ reject(err)
+ return
+ }
+ window[sidKey] = res.subscriber_id
+ resolve(res)
+ }, { event: 'queue', callback})
+ })
+}
+
export async function notificationUnsubscribe(account, sidKey = '__subscriber_id') {
if (!notifyAvailable()) return;
if (!window[sidKey]) return;
@@ -178,6 +302,53 @@ export async function notificationTake(account, removeTaskIds, forEach, abortCon
}
}
+export async function queueWatch(account, group, sidKey = '__subscriber_id') {
+ if (!notifyAvailable()) return
+ let url = notifyUrl(`/queues/watch/@${account}/${window[sidKey]}/group?o_scope=*&o=${group}`)
+ let response
+ try {
+ let request = Object.assign({}, request_base, {
+ method: 'get',
+ })
+ setSession(request)
+ response = await fetchEx(url, request)
+ if (response.ok) {
+ saveSession(response)
+ }
+ const result = await response.json()
+ if (result.status === 'ok') {
+ return
+ } else {
+ throw new Error('error: ' + result.error)
+ }
+ } catch (ex) {
+ throw ex
+ }
+}
+
+export async function queueWatchWs(account, group, sidKey = '__subscriber_id') {
+ if (!notifyWsHost()) return null
+ const xSession = notifySession()
+ return await new Promise(async (resolve, reject) => {
+ await notifyWsSend('queues/subscribe', {
+ account,
+ 'X-Session': xSession,
+ objects: {
+ [group]: {
+ type: 'group',
+ scope: '*',
+ },
+ },
+ }, (err, res) => {
+ if (err) {
+ reject(err)
+ return
+ }
+ resolve(res)
+ })
+ })
+}
+
export async function sendOffchainMessage(op) {
if (!notifyAvailable()) return;
let url = notifyUrl(`/msgs/send_offchain`);
@@ -194,7 +365,7 @@ export async function sendOffchainMessage(op) {
}
const result = await response.json();
if (result.status === 'ok') {
- return;
+ return result
} else {
throw new Error('error: ' +result.error);
}
@@ -204,11 +375,13 @@ export async function sendOffchainMessage(op) {
}
}
-if (process.env.BROWSER) {
+//if (process.env.BROWSER) {
window.getNotifications = getNotifications;
window.markNotificationRead = markNotificationRead;
window.notificationSubscribe = notificationSubscribe;
+ window.notificationSubscribeWs = notificationSubscribeWs
window.notificationUnsubscribe = notificationUnsubscribe;
window.notificationShallowUnsubscribe = notificationShallowUnsubscribe
window.notificationTake = notificationTake;
-}
+ window.queueWatch = queueWatch
+//}
diff --git a/src/utils/ServerApiClient.js b/src/utils/ServerApiClient.js
index 8d9fff818..7e8d04c8b 100644
--- a/src/utils/ServerApiClient.js
+++ b/src/utils/ServerApiClient.js
@@ -3,7 +3,7 @@ import { fetchEx } from 'golos-lib-js/lib/utils'
export function getHost() {
const { location, } = window;
if (process.env.NODE_ENV === 'development') {
- return location.protocol + '//'+ location.hostname + ':8080';
+ return location.protocol + '//'+ location.hostname + ':8088';
}
return location.origin;
}
diff --git a/src/utils/app/SplashUtils.js b/src/utils/app/SplashUtils.js
index fdd8b6658..1e0c4f305 100644
--- a/src/utils/app/SplashUtils.js
+++ b/src/utils/app/SplashUtils.js
@@ -1,10 +1,13 @@
export function hideSplash() {
- if (process.env.MOBILE_APP) {
- try {
+ try {
+ if (process.env.MOBILE_APP) {
navigator.splashscreen.hide()
- } catch (err) {
- console.error('hideSplash', err)
+ } else if (process.env.DESKTOP_APP) {
+ if (window.appSplash)
+ window.appSplash.contentLoaded()
}
+ } catch (err) {
+ console.error('hideSplash', err)
}
}
diff --git a/src/utils/app/UpdateUtils.js b/src/utils/app/UpdateUtils.js
index 2933db93d..f89da6693 100644
--- a/src/utils/app/UpdateUtils.js
+++ b/src/utils/app/UpdateUtils.js
@@ -55,10 +55,15 @@ export async function checkUpdates(timeout = 2000) {
if (versions[0]) {
const [ v, obj ] = versions[0]
if (obj.exe) {
+ let exeLink = new URL(obj.exe_url, updaterHost()).toString()
+ if (!isDesktop) {
+ exeLink = new URL('/api/html/' + path + '/' + v, updaterHost())
+ exeLink = exeLink.toString()
+ }
return {
version: v,
exe: obj.exe,
- exeLink: new URL(obj.exe_url, updaterHost()).toString(),
+ exeLink,
txt: obj.txt,
txtLink: new URL(obj.txt_url, updaterHost()).toString(),
title: tt('app_update.notify_VERSION', { VERSION: v }),
@@ -84,6 +89,6 @@ export async function getChangelog(txtLink) {
return res
} catch (err) {
console.error('getChangelog', err)
- return ''
+ throw err
}
}
diff --git a/src/utils/groups.js b/src/utils/groups.js
new file mode 100644
index 000000000..b99994d98
--- /dev/null
+++ b/src/utils/groups.js
@@ -0,0 +1,88 @@
+import { proxifyImageUrlWithStrip } from 'app/utils/ProxifyUrl'
+
+const getGroupMeta = (json_metadata) => {
+ let meta
+ if (json_metadata) {
+ meta = JSON.parse(json_metadata)
+ }
+ meta = meta || {} // node allows null, object, array... or empty json_metadata
+ return meta
+}
+
+const getGroupTitle = (meta, name, maxLength = 20) => {
+ const title = meta.title || name
+ let titleShr = title
+ if (titleShr.length > maxLength) {
+ titleShr = titleShr.substring(0, maxLength - 3) + '...'
+ }
+ return titleShr
+}
+
+const getGroupLogo = (json_metadata) => {
+ const meta = getGroupMeta(json_metadata)
+
+ let { logo } = meta
+ let isDefault = false
+ if (logo && /^(https?:)\/\//.test(logo)) {
+ const size = '75x75'
+ logo = proxifyImageUrlWithStrip(logo, size)
+ } else {
+ logo = require('app/assets/images/group.png')
+ isDefault = true
+ }
+ return {url: logo, isDefault }
+}
+
+const getMemberType = (member_list, username) => {
+ const mem = member_list.find(pgm => pgm.account === username)
+ const { member_type } = (mem || {})
+ return member_type
+}
+
+const getRoleInGroup = (group, username) => {
+ if (group.toJS) group = group.toJS()
+ const { owner, member_list } = group
+ const memberType = member_list && getMemberType(member_list, username)
+
+ const amOwner = owner === username
+ const amModer = amOwner || memberType === 'moder'
+ const amPending = memberType === 'pending'
+ const amMember = memberType === 'member'
+ const amBanned = memberType === 'banned'
+
+ return { amOwner, amModer, amPending, amMember, amBanned }
+}
+
+const opGroup = (op) => {
+ let group = ''
+ let requester = ''
+ let mentions = []
+ if (!op) return { group, requester, mentions }
+ const { extensions, memo } = op
+ if (extensions) {
+ for (const ext of extensions) {
+ if (ext && ext[0] === 0 && ext[1]) {
+ group = ext[1].group || group
+ mentions = ext[1].mentions || mentions
+ requester = ext[1].requester || requester
+ }
+ }
+ }
+ if (group) return { group, requester, mentions }
+ if (memo) { // donate
+ const { target } = memo
+ if (target && target.group) {
+ group = target.group
+ }
+ }
+ return { group, requester, mentions }
+}
+
+export {
+ getGroupMeta,
+ getGroupTitle,
+ getGroupLogo,
+ getMemberType,
+ getRoleInGroup,
+ opGroup,
+}
diff --git a/src/utils/initConfig.js b/src/utils/initConfig.js
index 290276805..2dce1ebd2 100644
--- a/src/utils/initConfig.js
+++ b/src/utils/initConfig.js
@@ -23,7 +23,10 @@ const loadMobileConfig = async () => {
if (cfg) {
try {
cfg = JSON.parse(cfg)
- // Add here migrations in future, if need
+ // Add here migrations
+ if (cfg.notify_service && !cfg.notify_service.host_ws) {
+ delete cfg.notify_service
+ }
cfg = { ...defaultCfg, ...cfg }
} catch (err) {
console.error('Cannot parse app_settings', err)
@@ -38,6 +41,7 @@ const loadMobileConfig = async () => {
if (cfg.images.use_img_proxy === undefined) {
cfg.images.use_img_proxy = true
}
+ cfg.app_version = defaultCfg.app_version
window.$GLS_Config = cfg
await initGolos()
}
diff --git a/src/utils/mentions.js b/src/utils/mentions.js
new file mode 100644
index 000000000..a4232b6b8
--- /dev/null
+++ b/src/utils/mentions.js
@@ -0,0 +1,18 @@
+
+export const accountNameRegEx = /^@[a-z0-9.-]+$/
+
+// TODO: can be renderMsg which also supports links, and rendering
+export function parseMentions(message) {
+ let mentions = new Set()
+ const { body } = message
+ const lines = body.split('\n')
+ for (const line of lines) {
+ const words = line.split(' ')
+ for (let word of words) {
+ if (word.length > 3 && accountNameRegEx.test(word)) {
+ mentions.add(word.slice(1))
+ }
+ }
+ }
+ return [...mentions]
+}
diff --git a/src/utils/misc.js b/src/utils/misc.js
index 23688d782..b777af5d0 100644
--- a/src/utils/misc.js
+++ b/src/utils/misc.js
@@ -5,6 +5,29 @@ const renderPart = (part, params) => {
return part
}
+const delay = (msec) => new Promise(resolve => setTimeout(resolve, msec))
+
+const maxDate = () => {
+ return new Date(4294967295 * 1000)
+}
+
+const maxDateStr = () => {
+ return maxDate().toISOString().split('.')[0]
+}
+
+const isBlockedByMe = (acc) => {
+ return acc && acc.relations && acc.relations.me_to_them === 'blocking'
+}
+
+const isBlockingMe = (acc) => {
+ return acc && acc.relations && acc.relations.they_to_me === 'blocking'
+}
+
export {
- renderPart
+ renderPart,
+ delay,
+ maxDate,
+ maxDateStr,
+ isBlockedByMe,
+ isBlockingMe,
}
diff --git a/src/utils/translateError.js b/src/utils/translateError.js
index 011d77a4c..92c78d421 100644
--- a/src/utils/translateError.js
+++ b/src/utils/translateError.js
@@ -1,6 +1,41 @@
import tt from 'counterpart'
+import { Asset } from 'golos-lib-js/lib/utils'
-export function translateError(string) {
+const getErrorData = (errPayload, errName, depth = 0) => {
+ //console.error('getErrorData', errPayload)
+ if (depth > 50) {
+ throw new Error('getErrorData - infinity loop detected...')
+ }
+ if (!errPayload) {
+ return null
+ }
+ console.error(errPayload.name)
+ if (errPayload.name === errName) {
+ let { stack } = errPayload
+ stack = stack && stack[0]
+ return stack ? stack.data : null
+ }
+ const { error, data } = errPayload
+ if (error) {
+ return getErrorData(error, errName, ++depth)
+ }
+ if (data) {
+ if (data.error) {
+ return getErrorData(data.error, errName, ++depth)
+ }
+ if (Array.isArray(data.stack)) {
+ for (const s of data.stack) {
+ const res = getErrorData(s, errName, ++depth)
+ if (res) {
+ return res
+ }
+ }
+ }
+ }
+ return null
+}
+
+export function translateError(string, errPayload) {
if (typeof(string) != 'string') return string
switch (string) {
case 'Account not found':
@@ -28,6 +63,64 @@ export function translateError(string) {
case 'Cannot increase reward of post within the last minute before payout':
return tt('g.cannot_increase_reward_of_post_within_the_last_minute_before_payout')
default:
- return string
+ break
+ }
+
+ if (string.includes(
+ 'Account exceeded maximum allowed bandwidth per vesting share'
+ )) {
+ string = tt('chain_errors.exceeded_maximum_allowed_bandwidth')
+ return string
}
+
+ if (string.includes(
+ 'Account does not have sufficient funds'
+ )) {
+ string = tt('donate_jsx.insufficient_funds') + '.'
+
+ let errData
+ try {
+ errData = getErrorData(errPayload, 'insufficient_funds')
+ if (errData && errData.required) {
+ let { required, exist } = errData
+ string += ' ' + tt('chain_errors.insufficient1')
+ string += Asset(required).floatString
+ exist = Asset(exist)
+ if (exist.gt(0)) {
+ string += tt('chain_errors.insufficient2')
+ string += exist.floatString
+ string += tt('chain_errors.insufficient3')
+ } else {
+ string += '.'
+ }
+ return string
+ }
+ } catch (err) {
+ console.error('getErrorData', err)
+ }
+ }
+
+ if (string.includes(
+ 'Too low golos power'
+ )) {
+ let errData
+ try {
+ errData = getErrorData(errPayload, 'logic_exception')
+ if (errData && errData.r) {
+ string = tt('messages.too_low_gp')
+ string += Asset(errData.r).floatString
+ string += tt('messages.too_low_gp2')
+ return string
+ }
+ } catch (err) {
+ console.error('getErrorData', err)
+ }
+ }
+
+ if (string.includes('You should be moder')) {
+ string = tt('messages.you_not_moder')
+ return string
+ }
+
+ return string
}
diff --git a/yarn.lock b/yarn.lock
index 06c7c8178..84575d8e5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1031,6 +1031,13 @@
dependencies:
regenerator-runtime "^0.13.4"
+"@babel/runtime@^7.12.0", "@babel/runtime@^7.18.3", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.7":
+ version "7.24.7"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.7.tgz#f4f0d5530e8dbdf59b3451b9b3e594b6ba082e12"
+ integrity sha512-UwgBRMjJP+xv857DCngvqXI3Iq6J4v0wXmwc6sapg+zyhbwmQX67LUEFrkK5tbyJ30jGuG3ZvWpBiB9LCy1kWw==
+ dependencies:
+ regenerator-runtime "^0.14.0"
+
"@babel/template@^7.16.7", "@babel/template@^7.3.3":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155"
@@ -1109,6 +1116,94 @@
dependencies:
postcss-value-parser "^4.2.0"
+"@emotion/babel-plugin@^11.11.0":
+ version "11.11.0"
+ resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c"
+ integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ==
+ dependencies:
+ "@babel/helper-module-imports" "^7.16.7"
+ "@babel/runtime" "^7.18.3"
+ "@emotion/hash" "^0.9.1"
+ "@emotion/memoize" "^0.8.1"
+ "@emotion/serialize" "^1.1.2"
+ babel-plugin-macros "^3.1.0"
+ convert-source-map "^1.5.0"
+ escape-string-regexp "^4.0.0"
+ find-root "^1.1.0"
+ source-map "^0.5.7"
+ stylis "4.2.0"
+
+"@emotion/cache@^11.11.0", "@emotion/cache@^11.4.0":
+ version "11.11.0"
+ resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff"
+ integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ==
+ dependencies:
+ "@emotion/memoize" "^0.8.1"
+ "@emotion/sheet" "^1.2.2"
+ "@emotion/utils" "^1.2.1"
+ "@emotion/weak-memoize" "^0.3.1"
+ stylis "4.2.0"
+
+"@emotion/hash@^0.9.1":
+ version "0.9.1"
+ resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43"
+ integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ==
+
+"@emotion/memoize@^0.8.1":
+ version "0.8.1"
+ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17"
+ integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==
+
+"@emotion/react@^11.8.1":
+ version "11.11.4"
+ resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.4.tgz#3a829cac25c1f00e126408fab7f891f00ecc3c1d"
+ integrity sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==
+ dependencies:
+ "@babel/runtime" "^7.18.3"
+ "@emotion/babel-plugin" "^11.11.0"
+ "@emotion/cache" "^11.11.0"
+ "@emotion/serialize" "^1.1.3"
+ "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1"
+ "@emotion/utils" "^1.2.1"
+ "@emotion/weak-memoize" "^0.3.1"
+ hoist-non-react-statics "^3.3.1"
+
+"@emotion/serialize@^1.1.2", "@emotion/serialize@^1.1.3":
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.4.tgz#fc8f6d80c492cfa08801d544a05331d1cc7cd451"
+ integrity sha512-RIN04MBT8g+FnDwgvIUi8czvr1LU1alUMI05LekWB5DGyTm8cCBMCRpq3GqaiyEDRptEXOyXnvZ58GZYu4kBxQ==
+ dependencies:
+ "@emotion/hash" "^0.9.1"
+ "@emotion/memoize" "^0.8.1"
+ "@emotion/unitless" "^0.8.1"
+ "@emotion/utils" "^1.2.1"
+ csstype "^3.0.2"
+
+"@emotion/sheet@^1.2.2":
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec"
+ integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==
+
+"@emotion/unitless@^0.8.1":
+ version "0.8.1"
+ resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3"
+ integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==
+
+"@emotion/use-insertion-effect-with-fallbacks@^1.0.1":
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963"
+ integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw==
+
+"@emotion/utils@^1.2.1":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4"
+ integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg==
+
+"@emotion/weak-memoize@^0.3.1":
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6"
+ integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==
+
"@eslint/eslintrc@^1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-1.1.0.tgz#583d12dbec5d4f22f333f9669f7d0b7c7815b4d3"
@@ -1124,6 +1219,26 @@
minimatch "^3.0.4"
strip-json-comments "^3.1.1"
+"@floating-ui/core@^1.0.0":
+ version "1.6.3"
+ resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.6.3.tgz#5e7bb92843f47fd1d8dcb9b3cc3c243aaed54f95"
+ integrity sha512-1ZpCvYf788/ZXOhRQGFxnYQOVgeU+pi0i+d0Ow34La7qjIXETi6RNswGVKkA6KcDO8/+Ysu2E/CeUmmeEBDvTg==
+ dependencies:
+ "@floating-ui/utils" "^0.2.3"
+
+"@floating-ui/dom@^1.0.1":
+ version "1.6.6"
+ resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.6.6.tgz#be54c1ab2d19112ad323e63dbeb08185fed0ffd3"
+ integrity sha512-qiTYajAnh3P+38kECeffMSQgbvXty2VB6rS+42iWR4FPIlZjLK84E9qtLnMTLIpPz2znD/TaFqaiavMUrS+Hcw==
+ dependencies:
+ "@floating-ui/core" "^1.0.0"
+ "@floating-ui/utils" "^0.2.3"
+
+"@floating-ui/utils@^0.2.3":
+ version "0.2.3"
+ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.2.3.tgz#506fcc73f730affd093044cb2956c31ba6431545"
+ integrity sha512-XGndio0l5/Gvd6CLIABvsav9HHezgDFFhDfHk1bvLfr9ni8dojqLSvBbotJEjmIwNHL7vK4QzBJTdBRoB+c1ww==
+
"@formatjs/ecma402-abstract@1.11.3":
version "1.11.3"
resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.11.3.tgz#f25276dfd4ef3dac90da667c3961d8aa9732e384"
@@ -1925,6 +2040,13 @@
hoist-non-react-statics "^3.3.0"
redux "^4.0.0"
+"@types/react-transition-group@^4.4.0":
+ version "4.4.10"
+ resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.10.tgz#6ee71127bdab1f18f11ad8fb3322c6da27c327ac"
+ integrity sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==
+ dependencies:
+ "@types/react" "*"
+
"@types/react@*", "@types/react@16 || 17":
version "17.0.39"
resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.39.tgz#d0f4cde092502a6db00a1cded6e6bf2abb7633ce"
@@ -2495,14 +2617,15 @@ assert-plus@^1.0.0:
integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=
assert@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/assert/-/assert-2.0.0.tgz#95fc1c616d48713510680f2eaf2d10dd22e02d32"
- integrity sha512-se5Cd+js9dXJnu6Ag2JFc00t+HmHOen+8Q+L7O9zI0PqQXr20uk2J0XQqMxZEeo5U50o8Nvmmx7dZrl+Ufr35A==
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/assert/-/assert-2.1.0.tgz#6d92a238d05dc02e7427c881fb8be81c8448b2dd"
+ integrity sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==
dependencies:
- es6-object-assign "^1.1.0"
- is-nan "^1.2.1"
- object-is "^1.0.1"
- util "^0.12.0"
+ call-bind "^1.0.2"
+ is-nan "^1.3.2"
+ object-is "^1.1.5"
+ object.assign "^4.1.4"
+ util "^0.12.5"
ast-types-flow@^0.0.7:
version "0.0.7"
@@ -2548,10 +2671,12 @@ autoprefixer@^10.4.2:
picocolors "^1.0.0"
postcss-value-parser "^4.2.0"
-available-typed-arrays@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
- integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
+available-typed-arrays@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz#a5cc375d6a03c2efc87a553f3e0b1522def14846"
+ integrity sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==
+ dependencies:
+ possible-typed-array-names "^1.0.0"
axe-core@^4.3.5:
version "4.4.1"
@@ -2941,6 +3066,17 @@ call-bind@^1.0.0, call-bind@^1.0.2:
function-bind "^1.1.1"
get-intrinsic "^1.0.2"
+call-bind@^1.0.5, call-bind@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.7.tgz#06016599c40c56498c18769d2730be242b6fa3b9"
+ integrity sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==
+ dependencies:
+ es-define-property "^1.0.0"
+ es-errors "^1.3.0"
+ function-bind "^1.1.2"
+ get-intrinsic "^1.2.4"
+ set-function-length "^1.2.1"
+
callsites@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
@@ -3299,6 +3435,11 @@ convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0:
dependencies:
safe-buffer "~5.1.1"
+convert-source-map@^1.5.0:
+ version "1.9.0"
+ resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f"
+ integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==
+
cookie-signature@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c"
@@ -3420,9 +3561,9 @@ core-js@^2.4.0:
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
core-js@^3.17.3:
- version "3.23.3"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.23.3.tgz#3b977612b15da6da0c9cc4aec487e8d24f371112"
- integrity sha512-oAKwkj9xcWNBAvGbT//WiCdOMpb9XQG92/Fe3ABFM/R16BsHgePG00mFOgKf7IsCtfj8tA1kHtf/VwErhriz5Q==
+ version "3.37.0"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.37.0.tgz#d8dde58e91d156b2547c19d8a4efd5c7f6c426bb"
+ integrity sha512-fu5vHevQ8ZG4og+LXug8ulUtVxjOcEYvifJr7L5Bfq9GOztVqsKd9/59hUk2ZSbCrS3BqUr3EpaYGIYzq7g3Ug==
core-js@^3.19.2:
version "3.21.0"
@@ -3505,11 +3646,11 @@ cross-env@^7.0.3:
cross-spawn "^7.0.1"
cross-fetch@^3.0.0:
- version "3.1.5"
- resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f"
- integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==
+ version "3.1.8"
+ resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82"
+ integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==
dependencies:
- node-fetch "2.6.7"
+ node-fetch "^2.6.12"
cross-spawn@^6.0.5:
version "6.0.5"
@@ -3838,6 +3979,15 @@ default-gateway@^6.0.3:
dependencies:
execa "^5.0.0"
+define-data-property@^1.0.1, define-data-property@^1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.4.tgz#894dc141bb7d3060ae4366f6a0107e68fbe48c5e"
+ integrity sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==
+ dependencies:
+ es-define-property "^1.0.0"
+ es-errors "^1.3.0"
+ gopd "^1.0.1"
+
define-lazy-prop@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f"
@@ -3850,11 +4000,12 @@ define-properties@^1.1.3:
dependencies:
object-keys "^1.0.12"
-define-properties@^1.1.4:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1"
- integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==
+define-properties@^1.2.1:
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c"
+ integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==
dependencies:
+ define-data-property "^1.0.1"
has-property-descriptors "^1.0.0"
object-keys "^1.1.1"
@@ -4014,6 +4165,14 @@ dom-helpers@^3.2.1:
dependencies:
"@babel/runtime" "^7.1.2"
+dom-helpers@^5.0.1:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
+ integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
+ dependencies:
+ "@babel/runtime" "^7.8.7"
+ csstype "^3.0.2"
+
dom-serializer@0:
version "0.2.2"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
@@ -4235,34 +4394,17 @@ es-abstract@^1.17.2, es-abstract@^1.19.0, es-abstract@^1.19.1:
string.prototype.trimstart "^1.0.4"
unbox-primitive "^1.0.1"
-es-abstract@^1.19.5, es-abstract@^1.20.0:
- version "1.20.1"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814"
- integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==
+es-define-property@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/es-define-property/-/es-define-property-1.0.0.tgz#c7faefbdff8b2696cf5f46921edfb77cc4ba3845"
+ integrity sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==
dependencies:
- call-bind "^1.0.2"
- es-to-primitive "^1.2.1"
- function-bind "^1.1.1"
- function.prototype.name "^1.1.5"
- get-intrinsic "^1.1.1"
- get-symbol-description "^1.0.0"
- has "^1.0.3"
- has-property-descriptors "^1.0.0"
- has-symbols "^1.0.3"
- internal-slot "^1.0.3"
- is-callable "^1.2.4"
- is-negative-zero "^2.0.2"
- is-regex "^1.1.4"
- is-shared-array-buffer "^1.0.2"
- is-string "^1.0.7"
- is-weakref "^1.0.2"
- object-inspect "^1.12.0"
- object-keys "^1.1.1"
- object.assign "^4.1.2"
- regexp.prototype.flags "^1.4.3"
- string.prototype.trimend "^1.0.5"
- string.prototype.trimstart "^1.0.5"
- unbox-primitive "^1.0.2"
+ get-intrinsic "^1.2.4"
+
+es-errors@^1.3.0:
+ version "1.3.0"
+ resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f"
+ integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==
es-module-lexer@^0.9.0:
version "0.9.3"
@@ -4278,11 +4420,6 @@ es-to-primitive@^1.2.1:
is-date-object "^1.0.1"
is-symbol "^1.0.2"
-es6-object-assign@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/es6-object-assign/-/es6-object-assign-1.1.0.tgz#c2c3582656247c39ea107cb1e6652b6f9f24523c"
- integrity sha512-MEl9uirslVwqQU369iHNWZXsI8yaZYGg/D65aOgZkeyFJwHYSxilf7rQzXKI7DdDuBPrBXbfk3sl9hJhmd5AUw==
-
escalade@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
@@ -4751,12 +4888,12 @@ file-loader@^6.2.0:
loader-utils "^2.0.0"
schema-utils "^3.0.0"
-file-selector@^0.4.0:
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.4.0.tgz#59ec4f27aa5baf0841e9c6385c8386bef4d18b17"
- integrity sha512-iACCiXeMYOvZqlF1kTiYINzgepRBymz1wwjiuup9u9nayhb6g4fSwiyJ/6adli+EPwrWtpgQAh2PoS7HukEGEg==
+file-selector@^0.6.0:
+ version "0.6.0"
+ resolved "https://registry.yarnpkg.com/file-selector/-/file-selector-0.6.0.tgz#fa0a8d9007b829504db4d07dd4de0310b65287dc"
+ integrity sha512-QlZ5yJC0VxHxQQsQhXvBaC7VRJ2uaxTf+Tfpu4Z/OcVQJVpZO+DGU0rkoVW5ce2SccxugvpBJoMvUs59iILYdw==
dependencies:
- tslib "^2.0.3"
+ tslib "^2.4.0"
filelist@^1.0.1:
version "1.0.2"
@@ -4799,6 +4936,11 @@ find-cache-dir@^3.3.1:
make-dir "^3.0.2"
pkg-dir "^4.1.0"
+find-root@^1.1.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4"
+ integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==
+
find-up@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7"
@@ -4889,9 +5031,8 @@ form-data@^3.0.0:
combined-stream "^1.0.8"
mime-types "^2.1.12"
-"formik@https://gitpkg.now.sh/golos-blockchain/formik/packages/formik?b697b6ef3f13c795bb862b35589fffde442ab465":
+formik@./git-deps/formik/packages/formik:
version "2.2.9"
- resolved "https://gitpkg.now.sh/golos-blockchain/formik/packages/formik?b697b6ef3f13c795bb862b35589fffde442ab465#a696d8404c7b8751188a426f347589fdc24f4ba7"
dependencies:
deepmerge "^2.1.1"
hoist-non-react-statics "^3.3.0"
@@ -4969,26 +5110,16 @@ function-bind@^1.1.1:
resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
-function.prototype.name@^1.1.5:
- version "1.1.5"
- resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621"
- integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
- es-abstract "^1.19.0"
- functions-have-names "^1.2.2"
+function-bind@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c"
+ integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==
functional-red-black-tree@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327"
integrity sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=
-functions-have-names@^1.2.2:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
- integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
-
gensync@^1.0.0-beta.2:
version "1.0.0-beta.2"
resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
@@ -5008,6 +5139,17 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1:
has "^1.0.3"
has-symbols "^1.0.1"
+get-intrinsic@^1.1.3, get-intrinsic@^1.2.4:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.4.tgz#e385f5a4b5227d449c3eabbad05494ef0abbeadd"
+ integrity sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==
+ dependencies:
+ es-errors "^1.3.0"
+ function-bind "^1.1.2"
+ has-proto "^1.0.1"
+ has-symbols "^1.0.3"
+ hasown "^2.0.0"
+
get-own-enumerable-property-symbols@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664"
@@ -5114,10 +5256,10 @@ globby@^11.0.1, globby@^11.0.4:
"gls-messenger-native-core@file:native_core":
version "1.0.0"
-golos-lib-js@^0.9.34:
- version "0.9.34"
- resolved "https://registry.yarnpkg.com/golos-lib-js/-/golos-lib-js-0.9.34.tgz#6c03fca60fc6749cb240e21793aa5f01ec389f80"
- integrity sha512-0UYh5/r5T8yz8rD40AEsoJH6txNeat+MrHF1LlgjnHIfJdI0qqUko+pNv75XlX5WEOOhyy6Ho3BjLimLtITtAg==
+golos-lib-js@^0.9.76:
+ version "0.9.76"
+ resolved "https://registry.yarnpkg.com/golos-lib-js/-/golos-lib-js-0.9.76.tgz#c589b26a8f77916529f2fb6e1020bb87f4cb0a7f"
+ integrity sha512-E9A9BnVoOoPjklxGJVxB3xKgLbLSCaXfW0lN4pipAKuokGEVFy8DPEwlUsFgmY9Jf9JFcwl5h6q2c1dzEuBGkQ==
dependencies:
abort-controller "^3.0.0"
assert "^2.0.0"
@@ -5141,6 +5283,13 @@ golos-lib-js@^0.9.34:
stream-browserify "^3.0.0"
ws "^8.2.3"
+gopd@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c"
+ integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==
+ dependencies:
+ get-intrinsic "^1.1.3"
+
graceful-fs@4.1.15:
version "4.1.15"
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00"
@@ -5173,11 +5322,6 @@ has-bigints@^1.0.1:
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113"
integrity sha512-LSBS2LjbNBTf6287JEbEzvJgftkF5qFkmCo9hDRpAzKhUOlJ+hx8dd4USs00SgsUNwc4617J9ki5YtEClM2ffA==
-has-bigints@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
- integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==
-
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@@ -5188,12 +5332,17 @@ has-flag@^4.0.0:
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
-has-property-descriptors@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861"
- integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==
+has-property-descriptors@^1.0.0, has-property-descriptors@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz#963ed7d071dc7bf5f084c5bfbe0d1b6222586854"
+ integrity sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==
dependencies:
- get-intrinsic "^1.1.1"
+ es-define-property "^1.0.0"
+
+has-proto@^1.0.1:
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.3.tgz#b31ddfe9b0e6e9914536a6ab286426d0214f77fd"
+ integrity sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==
has-symbols@^1.0.1, has-symbols@^1.0.2:
version "1.0.2"
@@ -5212,6 +5361,13 @@ has-tostringtag@^1.0.0:
dependencies:
has-symbols "^1.0.2"
+has-tostringtag@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.2.tgz#2cdc42d40bef2e5b4eeab7c01a73c54ce7ab5abc"
+ integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==
+ dependencies:
+ has-symbols "^1.0.3"
+
has@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
@@ -5228,6 +5384,13 @@ hash-base@^3.0.0:
readable-stream "^3.6.0"
safe-buffer "^5.2.0"
+hasown@^2.0.0:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003"
+ integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==
+ dependencies:
+ function-bind "^1.1.2"
+
he@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
@@ -5250,7 +5413,7 @@ history@4.10.1, history@^4.9.0:
tiny-warning "^1.0.0"
value-equal "^1.0.1"
-hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
+hoist-non-react-statics@^3.1.0, hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
@@ -5610,7 +5773,12 @@ is-boolean-object@^1.1.0:
call-bind "^1.0.2"
has-tostringtag "^1.0.0"
-is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.4:
+is-callable@^1.1.3:
+ version "1.2.7"
+ resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055"
+ integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==
+
+is-callable@^1.1.4, is-callable@^1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
@@ -5668,7 +5836,7 @@ is-module@^1.0.0:
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=
-is-nan@^1.2.1:
+is-nan@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/is-nan/-/is-nan-1.3.2.tgz#043a54adea31748b55b6cd4e09aadafa69bd9e1d"
integrity sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==
@@ -5676,7 +5844,7 @@ is-nan@^1.2.1:
call-bind "^1.0.0"
define-properties "^1.1.3"
-is-negative-zero@^2.0.1, is-negative-zero@^2.0.2:
+is-negative-zero@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150"
integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==
@@ -5741,13 +5909,6 @@ is-shared-array-buffer@^1.0.1:
resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6"
integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==
-is-shared-array-buffer@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79"
- integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==
- dependencies:
- call-bind "^1.0.2"
-
is-stream@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
@@ -5767,23 +5928,19 @@ is-symbol@^1.0.2, is-symbol@^1.0.3:
dependencies:
has-symbols "^1.0.2"
-is-typed-array@^1.1.3, is-typed-array@^1.1.9:
- version "1.1.9"
- resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.9.tgz#246d77d2871e7d9f5aeb1d54b9f52c71329ece67"
- integrity sha512-kfrlnTTn8pZkfpJMUgYD7YZ3qzeJgWUn8XfVYBARc4wnmNOmLbmuuaAs3q5fvB0UJOn6yHAKaGTPM7d6ezoD/A==
+is-typed-array@^1.1.3:
+ version "1.1.13"
+ resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.13.tgz#d6c5ca56df62334959322d7d7dd1cca50debe229"
+ integrity sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==
dependencies:
- available-typed-arrays "^1.0.5"
- call-bind "^1.0.2"
- es-abstract "^1.20.0"
- for-each "^0.3.3"
- has-tostringtag "^1.0.0"
+ which-typed-array "^1.1.14"
is-typedarray@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
-is-weakref@^1.0.1, is-weakref@^1.0.2:
+is-weakref@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2"
integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==
@@ -6791,6 +6948,11 @@ memfs@^3.1.2, memfs@^3.4.1:
dependencies:
fs-monkey "1.0.3"
+memoize-one@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-6.0.0.tgz#b2591b871ed82948aee4727dc6abceeeac8c1045"
+ integrity sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==
+
merge-descriptors@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61"
@@ -6955,10 +7117,10 @@ no-case@^3.0.4:
lower-case "^2.0.2"
tslib "^2.0.3"
-node-fetch@2.6.7:
- version "2.6.7"
- resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
- integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
+node-fetch@^2.6.12:
+ version "2.7.0"
+ resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d"
+ integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==
dependencies:
whatwg-url "^5.0.0"
@@ -7063,11 +7225,6 @@ object-inspect@^1.11.0, object-inspect@^1.9.0:
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.0.tgz#6e2c120e868fd1fd18cb4f18c31741d0d6e776f0"
integrity sha512-Ho2z80bVIvJloH+YzRmpZVQe87+qASmBUKZDWgx9cu+KDrX2ZDH/3tMy+gXbZETVGs2M8YdxObOh7XAtim9Y0g==
-object-inspect@^1.12.0:
- version "1.12.2"
- resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea"
- integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==
-
object-is@^1.0.1:
version "1.1.5"
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac"
@@ -7076,6 +7233,14 @@ object-is@^1.0.1:
call-bind "^1.0.2"
define-properties "^1.1.3"
+object-is@^1.1.5:
+ version "1.1.6"
+ resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.6.tgz#1a6a53aed2dd8f7e6775ff870bea58545956ab07"
+ integrity sha512-F8cZ+KfGlSGi09lJT7/Nd6KJZ9ygtvYC0/UYYLI9nmQKLMnydpB9yvbv9K1uSkEu7FU9vYPmVwLg328tX+ot3Q==
+ dependencies:
+ call-bind "^1.0.7"
+ define-properties "^1.2.1"
+
object-keys@^1.0.12, object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
@@ -7091,6 +7256,16 @@ object.assign@^4.1.0, object.assign@^4.1.2:
has-symbols "^1.0.1"
object-keys "^1.1.1"
+object.assign@^4.1.4:
+ version "4.1.5"
+ resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0"
+ integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==
+ dependencies:
+ call-bind "^1.0.5"
+ define-properties "^1.2.1"
+ has-symbols "^1.0.3"
+ object-keys "^1.1.1"
+
object.entries@^1.1.5:
version "1.1.5"
resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861"
@@ -7478,6 +7653,11 @@ portfinder@^1.0.28:
debug "^3.1.1"
mkdirp "^0.5.5"
+possible-typed-array-names@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f"
+ integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==
+
postcss-attribute-case-insensitive@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.0.tgz#39cbf6babf3ded1e4abf37d09d6eda21c644105c"
@@ -8069,7 +8249,7 @@ prop-types-extra@^1.0.1, prop-types-extra@^1.1.1:
react-is "^16.3.2"
warning "^4.0.0"
-prop-types@^15.5.10, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
+prop-types@^15.5.10, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1:
version "15.8.1"
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
@@ -8249,13 +8429,13 @@ react-dom@^17.0.2:
object-assign "^4.1.1"
scheduler "^0.20.2"
-react-dropzone@^12.0.4:
- version "12.0.4"
- resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-12.0.4.tgz#b88eeaa2c7118f7fd042404682b17a1d466f2fcf"
- integrity sha512-fcqHEYe1MzAghU6/Hz86lHDlBNsA+lO48nAcm7/wA+kIzwS6uuJbUG33tBZjksj7GAZ1iUQ6NHwjUURPmSGang==
+react-dropzone@^14.2.3:
+ version "14.2.3"
+ resolved "https://registry.yarnpkg.com/react-dropzone/-/react-dropzone-14.2.3.tgz#0acab68308fda2d54d1273a1e626264e13d4e84b"
+ integrity sha512-O3om8I+PkFKbxCukfIR3QAGftYXDZfOE2N1mr/7qebQJHs7U+/RSL/9xomJNpRg9kM5h9soQSdf0Gc7OHF5Fug==
dependencies:
attr-accept "^2.2.2"
- file-selector "^0.4.0"
+ file-selector "^0.6.0"
prop-types "^15.8.1"
react-error-overlay@^6.0.10:
@@ -8268,9 +8448,8 @@ react-fast-compare@^2.0.1:
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
-"react-foundation-components@git+https://github.com/golos-blockchain/react-foundation-components.git#6606fd5529f1ccbc77cd8d33a8ce139fdf8f9a11":
+react-foundation-components@./git-deps/react-foundation-components:
version "0.14.0"
- resolved "git+https://github.com/golos-blockchain/react-foundation-components.git#6606fd5529f1ccbc77cd8d33a8ce139fdf8f9a11"
dependencies:
babel-runtime "^6.25.0"
classnames "^2.2.5"
@@ -8428,6 +8607,21 @@ react-scripts@^5.0.0:
optionalDependencies:
fsevents "^2.3.2"
+react-select@^5.8.0:
+ version "5.8.0"
+ resolved "https://registry.yarnpkg.com/react-select/-/react-select-5.8.0.tgz#bd5c467a4df223f079dd720be9498076a3f085b5"
+ integrity sha512-TfjLDo58XrhP6VG5M/Mi56Us0Yt8X7xD6cDybC7yoRMUNm7BGO7qk8J0TLQOua/prb8vUOtsfnXZwfm30HGsAA==
+ dependencies:
+ "@babel/runtime" "^7.12.0"
+ "@emotion/cache" "^11.4.0"
+ "@emotion/react" "^11.8.1"
+ "@floating-ui/dom" "^1.0.1"
+ "@types/react-transition-group" "^4.4.0"
+ memoize-one "^6.0.0"
+ prop-types "^15.6.0"
+ react-transition-group "^4.3.0"
+ use-isomorphic-layout-effect "^1.1.2"
+
react-textarea-autosize@^8.3.3:
version "8.3.3"
resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz#f70913945369da453fd554c168f6baacd1fa04d8"
@@ -8437,6 +8631,16 @@ react-textarea-autosize@^8.3.3:
use-composed-ref "^1.0.0"
use-latest "^1.0.0"
+react-transition-group@^4.3.0:
+ version "4.4.5"
+ resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1"
+ integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==
+ dependencies:
+ "@babel/runtime" "^7.5.5"
+ dom-helpers "^5.0.1"
+ loose-envify "^1.4.0"
+ prop-types "^15.6.2"
+
react@^17.0.2:
version "17.0.2"
resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037"
@@ -8466,7 +8670,7 @@ readable-stream@^2.0.1:
string_decoder "~1.1.1"
util-deprecate "~1.0.1"
-readable-stream@^3.0.6, readable-stream@^3.5.0, readable-stream@^3.6.0:
+readable-stream@^3.0.6:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
@@ -8475,6 +8679,15 @@ readable-stream@^3.0.6, readable-stream@^3.5.0, readable-stream@^3.6.0:
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
+readable-stream@^3.5.0, readable-stream@^3.6.0:
+ version "3.6.2"
+ resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967"
+ integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==
+ dependencies:
+ inherits "^2.0.3"
+ string_decoder "^1.1.1"
+ util-deprecate "^1.0.1"
+
readdirp@~3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
@@ -8563,6 +8776,11 @@ regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.9:
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
+regenerator-runtime@^0.14.0:
+ version "0.14.1"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz#356ade10263f685dda125100cd862c1db895327f"
+ integrity sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==
+
regenerator-transform@^0.14.2:
version "0.14.5"
resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4"
@@ -8583,15 +8801,6 @@ regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.3.1:
call-bind "^1.0.2"
define-properties "^1.1.3"
-regexp.prototype.flags@^1.4.3:
- version "1.4.3"
- resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac"
- integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.3"
- functions-have-names "^1.2.2"
-
regexpp@^3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
@@ -8890,7 +9099,12 @@ semver@7.0.0, semver@~7.0.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
-semver@^5.5.0, semver@^5.6.0, semver@^5.7.1:
+semver@^5.5.0:
+ version "5.7.2"
+ resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8"
+ integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==
+
+semver@^5.6.0, semver@^5.7.1:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@@ -8970,6 +9184,18 @@ serve-static@1.14.2:
parseurl "~1.3.3"
send "0.17.2"
+set-function-length@^1.2.1:
+ version "1.2.2"
+ resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.2.2.tgz#aac72314198eaed975cf77b2c3b6b880695e5449"
+ integrity sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==
+ dependencies:
+ define-data-property "^1.1.4"
+ es-errors "^1.3.0"
+ function-bind "^1.1.2"
+ get-intrinsic "^1.2.4"
+ gopd "^1.0.1"
+ has-property-descriptors "^1.0.2"
+
setprototypeof@1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656"
@@ -9108,7 +9334,7 @@ source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, sourc
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
-source-map@^0.5.0:
+source-map@^0.5.0, source-map@^0.5.7:
version "0.5.7"
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
@@ -9153,6 +9379,11 @@ spdy@^4.0.2:
select-hose "^2.0.0"
spdy-transport "^3.0.0"
+speakingurl@^14.0.1:
+ version "14.0.1"
+ resolved "https://registry.yarnpkg.com/speakingurl/-/speakingurl-14.0.1.tgz#f37ec8ddc4ab98e9600c1c9ec324a8c48d772a53"
+ integrity sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==
+
sprintf-js@^1.0.3, sprintf-js@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673"
@@ -9255,15 +9486,6 @@ string.prototype.trimend@^1.0.4:
call-bind "^1.0.2"
define-properties "^1.1.3"
-string.prototype.trimend@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0"
- integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.4"
- es-abstract "^1.19.5"
-
string.prototype.trimstart@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.4.tgz#b36399af4ab2999b4c9c648bd7a3fb2bb26feeed"
@@ -9272,15 +9494,6 @@ string.prototype.trimstart@^1.0.4:
call-bind "^1.0.2"
define-properties "^1.1.3"
-string.prototype.trimstart@^1.0.5:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef"
- integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==
- dependencies:
- call-bind "^1.0.2"
- define-properties "^1.1.4"
- es-abstract "^1.19.5"
-
string_decoder@^1.1.1:
version "1.3.0"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
@@ -9356,6 +9569,11 @@ stylehacks@^5.0.3:
browserslist "^4.16.6"
postcss-selector-parser "^6.0.4"
+stylis@4.2.0:
+ version "4.2.0"
+ resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51"
+ integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==
+
supports-color@^5.3.0, supports-color@^5.5.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
@@ -9638,6 +9856,11 @@ tslib@^2.2.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
+tslib@^2.4.0:
+ version "2.6.3"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.3.tgz#0438f810ad7a9edcde7a241c3d80db693c8cbfe0"
+ integrity sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==
+
tsscmp@1.0.6:
version "1.0.6"
resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb"
@@ -9728,16 +9951,6 @@ unbox-primitive@^1.0.1:
has-symbols "^1.0.2"
which-boxed-primitive "^1.0.2"
-unbox-primitive@^1.0.2:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
- integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==
- dependencies:
- call-bind "^1.0.2"
- has-bigints "^1.0.2"
- has-symbols "^1.0.3"
- which-boxed-primitive "^1.0.2"
-
uncontrollable@^5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/uncontrollable/-/uncontrollable-5.1.0.tgz#7e9a1c50ea24e3c78b625e52d21ff3f758c7bd59"
@@ -9845,6 +10058,11 @@ use-isomorphic-layout-effect@^1.0.0:
resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.1.tgz#7bb6589170cd2987a152042f9084f9effb75c225"
integrity sha512-L7Evj8FGcwo/wpbv/qvSfrkHFtOpCzvM5yl2KVyDJoylVuSvzphiiasmjgQPttIGBAy2WKiBNR98q8w7PiNgKQ==
+use-isomorphic-layout-effect@^1.1.2:
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz#497cefb13d863d687b08477d9e5a164ad8c1a6fb"
+ integrity sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==
+
use-latest@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/use-latest/-/use-latest-1.2.0.tgz#a44f6572b8288e0972ec411bdd0840ada366f232"
@@ -9867,16 +10085,15 @@ util.promisify@~1.0.0:
has-symbols "^1.0.1"
object.getownpropertydescriptors "^2.1.0"
-util@^0.12.0:
- version "0.12.4"
- resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253"
- integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==
+util@^0.12.5:
+ version "0.12.5"
+ resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc"
+ integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==
dependencies:
inherits "^2.0.3"
is-arguments "^1.0.4"
is-generator-function "^1.0.7"
is-typed-array "^1.1.3"
- safe-buffer "^5.1.2"
which-typed-array "^1.1.2"
utila@~0.4:
@@ -10162,17 +10379,16 @@ which-boxed-primitive@^1.0.2:
is-string "^1.0.5"
is-symbol "^1.0.3"
-which-typed-array@^1.1.2:
- version "1.1.8"
- resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.8.tgz#0cfd53401a6f334d90ed1125754a42ed663eb01f"
- integrity sha512-Jn4e5PItbcAHyLoRDwvPj1ypu27DJbtdYXUa5zsinrUx77Uvfb0cXwwnGMTn7cjUfhhqgVQnVJCwF+7cgU7tpw==
+which-typed-array@^1.1.14, which-typed-array@^1.1.2:
+ version "1.1.15"
+ resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.15.tgz#264859e9b11a649b388bfaaf4f767df1f779b38d"
+ integrity sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==
dependencies:
- available-typed-arrays "^1.0.5"
- call-bind "^1.0.2"
- es-abstract "^1.20.0"
+ available-typed-arrays "^1.0.7"
+ call-bind "^1.0.7"
for-each "^0.3.3"
- has-tostringtag "^1.0.0"
- is-typed-array "^1.1.9"
+ gopd "^1.0.1"
+ has-tostringtag "^1.0.2"
which@^1.2.9, which@^1.3.1:
version "1.3.1"
@@ -10403,9 +10619,9 @@ ws@^7.4.6:
integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==
ws@^8.2.3:
- version "8.8.0"
- resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.0.tgz#8e71c75e2f6348dbf8d78005107297056cb77769"
- integrity sha512-JDAgSYQ1ksuwqfChJusw1LSJ8BizJ2e/vVu5Lxjq3YvNJNlROv1ui4i+c/kUUrPheBvQl4c5UbERhTwKa6QBJQ==
+ version "8.17.0"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-8.17.0.tgz#d145d18eca2ed25aaf791a183903f7be5e295fea"
+ integrity sha512-uJq6108EgZMAl20KagGkzCKfMEjxmKvZHG7Tlq0Z6nOky7YF7aq4mOx6xK8TJ/i1LeK4Qus7INktacctDgY8Ow==
ws@^8.4.2:
version "8.5.0"