Как убрать глобальный скролл тинькофф
Перейти к содержимому

Как убрать глобальный скролл тинькофф

  • автор:

Инструкция по использованию ЛК Тинькофф

Главная страница → Значок голосового помощника «Олег»:

Отправляете текст «Пуш вместо смс»

Посредством кнопок под сообщениями:

Подключить → Все → Да

1.4 Оформление второй дополнительной карты.

Главная страница → Значок голосового помощника «Олег»:

Оформить дополнительную карту → Себе → Виртуальная → Да, выпускаем

Последние цифры карт замазаны. У двух карт общий счёт, как и баланс.

1.5 Переход на тариф с бесплатным обслуживанием.

Отправляете в тех. поддержку текст наподобии

«Здравствуйте, есть возможность удалить счёт? Мне не нравится цена за обслуживание карты. Хочу перейти в другой банк.»

Диалог получается приблизительно таким

Если счёт прогрет и имеет немалый оборот, тариф сменят почти сразу же в чате.

ЧАСТО ЗАДАВАЕМЫЕ ВОПРОСЫ.

1) Можно ли использовать два аккаунта на одном устройстве?

На устройствах с установленными прошивками от компаний Xiaomi и Samsung (MIUI и OneUI соответственно) можно воспользоваться встроенной функцией «Клонирование приложений».

На смартфонах под управлением ос Android с другими прошивками можно использовать сторонний софт, который можно найти в Play Маркете и подобных площадках.

На смартфонах под управлением ос IOS без вмешательства в системные процессы такое сделать невозможно.

2) Можно ли использовать аккаунт через веб-версию?

Нет, такая возможность отсутствует.

3) При переводе в приложении требуется код-подтверждение. Что делать?

Такое происходит обычно когда на устройстве до выданного аккаунта использовался другой аккаунт, решается трёх-дневным перерывом в использовании аккаунта.

4) При попытке просмотра реквизитов карты появляется надпись «Не удалось загрузить» в верхней части экрана. Что делать?

Такое обычно происходит обычно при входе в аккаунт с «грязного» (На котором было несколько аккаунтов Тинькофф) устройства. Решается входом в аккаунт с другого устройства/эмулятора/клонера приложений или трёх-дневным перерывом в использовании аккаунта.

5) Карта заблокирована, переводы недоступны. Что делать?

В таком случае особо ничего сделать нельзя, обычно для разблокировки нужно принять видеозвонок, принять который у нас возможности нет.

Удачной покупки и использования!

Введение

Angular предоставляет удобный декларативный способ подписки на события в шаблоне, с помощью синтаксиса (eventName)=»onEventName($event)» . Вместе с политикой проверки изменений ChangeDetectionStrategy.OnPush подобный подход автоматически запускает цикл проверки изменений только по интересующему нас пользовательскому вводу. Иными словами, если мы слушаем (input) событие на элементе, то проверка изменений не будет запускаться, если пользователь просто кликает по полю ввода. Это значительно улучшает
производительность, по сравнению с политикой по умолчанию ( ChangeDetectionStrategy.Default ). В директивах мы также можем подписаться на события на хост-элементе через декоратор @HostListener(‘eventName’) .

В моей практике нередко встречаются случаи, когда обработка конкретного события требуется только при выполнении какого-либо условия. т.е. обработчик выглядит примерно так:

class ComponentWithEventHandler < // . onEvent(event: Event) < if (!this.condition) < return; >// Handling event . > >

Даже если условие не выполнилось и никакие действия по факту не произошли, цикл проверки изменений всё равно будет запущен. В случае с частыми событиями, вроде scroll или mousemove , это может негативно отразиться на производительности приложения.

В библиотеке UI компонентов, над которой я работаю, подписка на mousemove внутри выпадающих меню вызвала пересчет изменений вверх по всему дереву компонентов на каждое движение мыши. Следить за мышью было необходимо для реализации корректного поведения меню, но это явно стоило оптимизировать. Подробнее об этом ниже.

Подобные моменты особенно важны для универсальных UI элементов. Их на странице может присутствовать множество, а приложения бывают очень сложными и требовательными к производительности.

Исправить ситуацию можно, делая подписку на события в обход ngZone , например, с помощью Observable.fromEvent и запускать проверку изменений руками, вызывая changeDetectorRef.markForCheck() . Однако, это добавляет кучу лишней работы и лишает возможности использовать удобные встроенные инструменты Angular.

Ни для кого не секрет, что Angular позволяет подписываться на так называемые псевдособытия, уточняя какие именно события нас интересуют. Мы можем написать (keydown.enter)=»onEnter($event)» и обработчик (а вместе с ним и цикл проверки изменений) вызовется только при нажатии клавиши Enter .Остальные нажатия будут игнорироваться. В этой статье мы разберёмся, как можно воспользоваться тем же подходом, что и Angular, для оптимизации обработки событий. А в качестве бонуса добавим модификаторы .prevent и .stop , которые будут отменять поведение по умолчанию и останавливать всплытие события автоматически.

EventManagerPlugin

Для обработки событий Angular использует класс EventManager . Он имеет набор так называемых плагинов, расширяющих абстрактный EventManagerPlugin и делегирует обработку подписки на событие в тот плагин, который поддерживает данное событие (по имени). Внутри Angular предусмотрены несколько плагинов, среди которых обработка HammerJS событий и плагин, отвечающий за составные события, вроде keydown.enter . Это внутренняя реализация Angular, и данный подход может измениться. Однако, с момента создания issue про переработку этого решения прошло уже 3 года, и никаких подвижек в этом направлении не произошло:

Что интересно в этом для нас? Несмотря на то, что эти классы внутренние и отнаследоваться от них нельзя, токен, отвечающий за внедрение зависимостей для плагинов — публичный. Это значит, мы можем писать свои плагины и расширять ими встроенный механизм обработки событий.

Если посмотреть исходный код EventManagerPlugin , можно заметить, что мы и не сможем от него отнаследоваться, в большинстве своём он абстрактный и реализовать свой класс, отвечающий его требованиям не составляет труда:

Грубо говоря, плагин должен уметь определять, работает ли он с данным событием и должен уметь добавлять обработчик события и глобальные обработчики (на body , window и document ). Нас будут интересовать модификаторы .filter , .prevent и .stop . Для привязки их к нашему плагину реализуем обязательный метод supports :

const FILTER = '.filter'; const PREVENT = '.prevent'; const STOP = '.stop'; class FilteredEventPlugin < supports(event: string): boolean < return ( event.includes(FILTER) || event.includes(PREVENT) || event.includes(STOP) ); >>

Так EventManager поймёт, что события, в имени которых присутствуют определённые модификаторы, нужно передать на обработку в наш плагин. Затем нам нужно реализовать добавление обработчиков на события. Глобальные обработчики нас не интересуют, в их случае необходимость в подобных инструментах встречается существенно реже, а реализация была бы сложнее. Поэтому мы просто уберём из имени события наши модификаторы и вернём его в EventManager , чтобы он подобрал правильный встроенный плагин для обработки:

class FilteredEventPlugin < supports(event: string): boolean < // . >addGlobalEventListener( element: string, eventName: string, handler: Function, ): Function < const event = eventName .replace(FILTER, '') .replace(PREVENT, '') .replace(STOP, ''); return this.manager.addGlobalEventListener(element, event, handler); >>

В случае с событием на обычном элементе, нам нужно написать свою логику. Для этого мы обернём обработчик в замыкание и передадим событие без наших модификаторов назад в EventManager , вызвав его вне ngZone , чтобы избежать запуск цикла проверки изменений:

class FilteredEventPlugin < supports(event: string): boolean < // . >addEventListener( element: HTMLElement, eventName: string, handler: Function, ): Function < const event = eventName .replace(FILTER, '') .replace(PREVENT, '') .replace(STOP, ''); // Обёртка над нашим обработчиком const filtered = (event: Event) =>< // . >; const wrapper = () => this.manager.addEventListener(element, event, filtered); return this.manager.getZone().runOutsideAngular(wrapper); > /* addGlobalEventListener(. ): Function < . >*/ >

На данном этапе у нас есть: имя события, само событие и элемент, на котором оно слушается. Обработчик, который попадает сюда — не исходный обработчик, назначенный на это событие, а конец цепочки замыканий, созданных Angular для своих целей.

Одним решением могло бы стать добавление атрибута на элемент, отвечающего за то, вызывать обработчик или нет. Иногда для принятия решения необходимо проанализировать само событие: было ли отменено действие по умолчанию, какой элемент является источником события и т.д. Для этого недостаточно атрибута, нам нужно найти способ задать функцию-фильтр, получающую на вход событие и возвращающую true или false . Тогда мы могли бы описать наш обработчик следующим образом:

const filtered = (event: Event) => < const filter = getOurHandler(some_arguments); if ( !eventName.includes(FILTER) || !filter || filter(event) ) < if (eventName.includes(PREVENT)) < event.preventDefault(); >if (eventName.includes(STOP)) < event.stopPropagation(); >this.manager.getZone().run(() => handler(event)); > >;

Решение

Решением может стать синглтон сервис, хранящий соответствия элементов парам событие/фильтр и вспомогательные сущности для задания этих соответствий. Разумеется, на одном элементе может быть несколько обработчиков на одно и то же событие, но, как правило, это могут быть одновременно заданные @HostListener и обработчик, установленный на этот компонент в шаблоне на уровень выше. Эту ситуацию мы предусмотрим, другие же случаи нас мало интересуют ввиду своей специфичности.

Основной сервис довольно простой и состоит из мапы и пары методов для задания, получения и очистки фильтров:

export type Filter = (event: Event) => boolean; export type Filters = <[key: string]: Filter>; class FilteredEventMainService < private elements: Map= new Map(); register(element: Element, filters: Filters) < this.elements.set(element, filters); >unregister(element: Element) < this.elements.delete(element); >getFilter(element: Element, event: string): Filter | null < const map = this.elements.get(element); return map ? map[event] || null : null; >>

Таким образом, мы можем внедрить этот сервис в плагин и получать фильтр, передавая элемент и имя события. Для использования в связке с @HostListener добавим ещё один небольшой сервис, который будет жить вместе с компонентом и очищать соответствующие фильтры при его удалении:

export class EventFiltersService < constructor( @Inject(ElementRef) private readonly elementRef: ElementRef, @Inject(FilteredEventMainService) private readonly mainService: FilteredEventMainService, ) <>ngOnDestroy() < this.mainService.unregister(this.elementRef.nativeElement); >register(filters: Filters) < this.mainService.register(this.elementRef.nativeElement, filters); >>

Для добавления фильтров на элементы можно сделать аналогичную директиву:

class EventFiltersDirective < @Input() set eventFilters(filters: Filters) < this.mainService.register(this.elementRef.nativeElement, filters); >constructor( @Inject(ElementRef) private readonly elementRef: ElementRef, @Inject(FilteredEventMainService) private readonly mainService: FilteredEventMainService, ) <> ngOnDestroy() < this.mainService.unregister(this.elementRef.nativeElement); >>

В случае, если внутри компонента присутствует сервис для фильтрации событий, мы не будем позволять вешать на него фильтры через директиву. В конце концов, это почти всегда можно сделать, просто обернув компонент элементом, на который будет назначена наша директива. Чтобы понять, что на данном элементе уже присутствует сервис, мы опционально внедрим его в директиву:

class EventFiltersDirective < // . constructor( @Optional() @Self() @Inject(FiltersService) private readonly filtersService: FiltersService | null, ) <>// . >

Если этот сервис присутствует, будем выводить сообщение о том, что директива к нему не применима:

class EventFiltersDirective < @Input() set eventFilters(filters: Filters) < if (this.eventFiltersService === null) < console.warn(ALREADY_APPLIED_MESSAGE); return; >this.mainService.register(this.elementRef.nativeElement, filters); > // . >

Применение на практике

Весь описанный код можно найти на Stackblitz:

В качестве примеров использования там показаны мнимый select — компонент внутри модального окна — и контекстное меню в роли его выпадашки. В случае с контекстным меню, если вы проверите любую реализацию, то увидите, что поведение всегда следующее: при наведении мыши на пункт, он фокусируется, при дальнейшем нажатии стрелочек на клавиатуре, фокус перемещается по пунктам, но если подвигать мышью, фокус возвращается в элемент, находящийся под указателем мыши. Казалось бы, это поведение несложно реализовать, однако, лишние реакции на событие mousemove могут запускать десятки бесполезных циклов проверки изменений. Установив в качестве фильтра проверку на сфокусированность target элемента события, мы можем отсечь эти лишние срабатывания, оставив только те, что реально переносят фокус.

Также, в этом select -компоненте есть фильтрация на @HostListener подписках. При нажатии клавиши Esc внутри попапа, он должен закрываться. Это должно происходить, только если это нажатие не было необходимо в каком-то вложенном компоненте и не было обработано в нём. В select нажатие Esc вызывает закрытие выпадашки и возврат фокуса в само поле, но если он уже закрыт, он не должен препятствовать всплытию события и последующему закрытию модального окна. Таким образом, обработку можно описать декоратором:

@HostListener(‘keydown.esc.filtered.stop’) , при фильтре: () => this.opened .

Поскольку select является компонентом с несколькими фокусируемыми элементами, отслеживание его общей сфокусированности возможно через всплывающие события focusout . Они будут происходить при всех изменениях фокуса, в том числе, не покидающих границы компонента. У этого события есть поле relatedTarget , отвечающее за то, куда перемещается фокус. Проанализировав его, мы можем понять, вызывать ли нам аналог события blur для нашего компонента:

class SelectComponent < // . @HostListener('focusout.filtered') onBlur() < this.opened = false; >// . >

Фильтр, при этом, выглядит так:

const focusOutFilter = (: FocusEvent) => !this.elementRef.nativeElement.contains(relatedTarget);

Вывод

К сожалению, встроенная обработка составных нажатий клавиш в Angular всё равно запустится в NgZone , а значит вызовет проверку изменений. При желании мы могли бы не прибегать к встроенной обработке, но выигрыш в производительности будет невелик, а углубления во внутреннюю “кухню” Angular чреваты поломками при обновлении. Поэтому мы либо должны отказаться от составного события, либо использовать фильтр аналогично граничному оператору и просто не вызывать обработчик там, где он не актуален.

Вклинивание во внутреннюю обработку событий Angular — затея авантюрная, так как внутренняя реализация может измениться в будущем. Это обязывает нас следить за обновлениями, в частности, за задачей на GitHub, приведённой во второй секции статьи. Зато теперь мы можем удобно фильтровать выполнение обработчиков и запуск проверки изменений, у нас появилась возможность удобно применять типичные для обработки событий методы preventDefault и stopPropagation прямо при объявлении подписки. Из заделов на будущее — было бы удобнее объявлять фильтры для @HostListener -ов прямо рядом с ними с помощью декораторов. В следующей статье я планирую рассказать о нескольких декораторах, которые мы у себя создали, и попробую реализовать это решение.

  • Блог компании TINKOFF
  • Веб-разработка
  • JavaScript
  • Angular

Как распознать мошенничество при работе с финансовыми ботами и как избежать потерь?

У меня сложилась такая ситуация: просматривала как-то вакансии по удаленной работе, в понедельник звонит человек предлагает вакансии, я соглашаюсь рассмотреть. Устанавливаем Скайп для последующего общения с человеком. Регистрируем аккаунт в телеграмм, бот MFinanc, при регистрации общалась с девушкой. Это рабочий аккаунт, как она сказала. Так получилось, что в Сбербанк надо было зайти и я по своей невнимательности с кредитной карты перевела сумму 4999, на дебетовой карте такой суммы не было и пополнила свой номер телефона, потом она сказала, что не должно так быть, что не должно было пополниться, так как сумму вводила сначала ставила «0» и вводила сумму, якобы так она не спишется и подали запрос на возврат средств. Средства на карту не вернулись, со счета в мобильной связи деньги ушли. А ушли деньги на рабочий мой аккаунт, после запроса в телеграмме. А счёт там долларовый. После всего этого она перевела меня на специалиста-аналитка, который теперь со мной общается. Он начал мне объяснять, что чтобы вывести деньги, чтобы конвертировать валюту надо прокрутить кредитный рейтинг. Это для того, чтобы в дальнейшем при выполнении работы я могла выводить деньги. И чтобы прокрутить кредитный рейтинг надо было переводить деньги между своими счетами. Как он мне объяснил, сейчас санкции и не все банки конвертируют валюту. Уточнил какие есть банки. У меня есть Сбербанк и Альфа банк. Они не конвертируют валюту, это он мне так объяснил, спросил, что есть ещё. Может есть озон, я говорю есть и озон банк оказывается тоже был там у меня. На кредитке в Сбере была сумма 100000, перевела на озон банк 97000, он говорит, что переводите все между своими счетами и беспокоиться не о чем. Так как озон тоже не конвертирует валюту, но банк ВТБ является их партнёром, то через запрс в телеграмм перевела с озона деньги, перевелись на мой аккаунт в телеграм, сумма личных средств стала видна в долларах, и снова через запрос в телеграм написали на вывод средств обратно на озон банк. Прошло некоторое время, а деньги на озон не поступают. Говорю менеджеру, а он мне пишет, что не докрутили кредитный рейтинг, надо увеличин лимит по кредитной карте. Не хотелось

Уде ничего брать, но деньги хотелось вывести, все таки перевела Уже такую сумму. Увеличиваем лимит, увеличили ещё на 69000 т. Снова переводим на озон, запрос через телеграм и деньги снова падают на мой аккаунт. Снова пишем запрос на вывод и снова не докрутили кредитный потенциал. Пытаемся оыормин в Сбере кредит-отказ, пытаемся оформить в Сбере авто кредит — отказ. Пишет запрос на вывод, ждём, на озон ничего не приходит. Дальше говорит, в Альфа банке берём кредит, что как только выведем деньги на озон сразу закроем. Взяла кредит, дали 297000 + к этой сумме страховка. Перевела на озон 297000 т, через запрос в телеграм сумма эта тоже падает на аккаунт в телеграм. Сумма в долларах меняется. Снова запрос на вывод, и снова не докрутили. Берём кредитку в альфе и снова та же схема. Уверял, что вот все, уже выведем и деньги придут на озон. Ждала в течение дня, но так и не пришло ничего, пишу менеджеру, а он мне говорит, что скорее всего надо лимит повысить ещё. Оформляем Тинькофф пока просто обычную карту. Деньги так и висят в телеграм сейчас. Менеджер на выходных сейчас.

В ходе разговора выяснилон, что сумма 4999 это необходимо было для активации рабочего аккаунта. И если не сделать прокрутку кредитного рейтинга, то ещё и за аккаунт комиссию будут брать. Я уточнила, что не достаточно этой суммы, он объясняет, что чтобы вводит потом деньги нужно сделать эту прокрутку.

Как это остановить? До какого момента будет идти прокрутка кредитного рейтинга, и увеличение лимита? У него спрашиваю, а он говорит, что все хорошо будет, это же на вашем счёте, доступа у них нет к нему. Так происходит из-за санкций. Паспортные данные нигде не вводила, только ФИО дату рождения и телефон. Не знаю, что думать, уже неделя прошла? Что дальше будет. Мне страшно, столько кредитов оформила. Это развод на деньги или что? Как это остановить?

Условия премиум-сервиса

Плата списывается раз в месяц. Дата всегда одна и та же — она зависит от того, в какой день месяца вы подключили премиум-сервис. В этот же день продлевается премиальное обслуживание.

Узнать дату продления премиум-сервиса можно так:

в мобильном приложении Тинькофф: «Главная» → «Кэшбэк и бонусы» → Tinkoff Premium → знак шестеренки;
в личном кабинете на tinkoff.ru: «Главная» → вкладка «Премиум».

Период действия премиум-сервиса и расчетный период ваших карт может не совпадать. Это связано с тем, что действие сервиса начинается с даты подключения, а расчетный период карты — на следующий день после даты выписки. Как посмотреть выписку по карте

Какие есть способы пользоваться премиум-сервисом бесплатно?

Нужно выполнить одно из условий.

Тратить от 200 000 ₽ и сохранять на счетах от 1 000 000 ₽ в период действия сервиса .

К тратам относятся покупки по всем вашим картам Тинькофф, включая кредитные, дополнительные и непремиальные. Переводы и снятие наличных покупками не считаются.

Неснижаемый остаток 1 000 000 ₽ должен быть на счетах каждый день в течение периода действия сервиса. Учитывается общая сумма на всех ваших вкладах и дебетовых счетах, включая накопительные, карточные и брокерские. Совместные счета тоже учитываются, но только если их открыли вы.

Сохранять на счетах от 3 000 000 ₽. Общий баланс на всех ваших вкладах и дебетовых счетах должен быть не меньше этой суммы каждый день в течение всего периода действия сервиса . Получать официальную зарплату от 400 000 ₽ на любую карту Тинькофф — учитываются только поступления от юрлиц с пометкой «Заработная плата». Если хотя бы за один из последних трех месяцев вы заработали 400 000 ₽ или больше, премиальный сервис будет бесплатным. Вот как мы считаем.

Допустим, дата продления Tinkoff Premium у вас 10 июня. Система проверит поступления от работодателя за период с 1 апреля по 10 июня — то есть за два полных календарных месяца и за 10 дней июня. Если в одном из месяцев, например в мае, вы получили аванс и зарплату на общую сумму 420 000 ₽, этого достаточно, чтобы бесплатно продлить премиальный сервис.

В остальных случаях плата за премиальный сервис составляет 1990 ₽.

Как отключить премиум-сервис?

Вот как это сделать в мобильном приложении Тинькофф: «Главная» → «Кэшбэк и бонусы» → блок Tinkoff Premium → иконка шестеренки в правом верхнем углу → «Отключить Tinkoff Premium». Также отключить сервис можно в чате поддержки на сайте tinkoff.ru или в приложении Тинькофф Инвестиций.

Отказ от премиального сервиса бесплатный. Но банк может списать плату за оформление премиальных металлических карт.

Этого не произойдет, если за один из периодов действия премиум-сервиса вы:
потратили 200 000 ₽ на покупки со всех карт Тинькофф — включая кредитные и непремиальные;

или сохранили общий остаток свыше 3 000 000 ₽ на всех счетах Тинькофф — включая брокерские и накопительные.

Также оформление металлических карт будет бесплатным, если вы пользовались сервисом Tinkoff Premium минимум три месяца.

Если ни одно из этих условий не было выполнено, спишем 1990 ₽ за каждую выпущенную металлическую карту.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *