Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Проматывать рекомендации к элементу, открытому из публичного экрана плейлиста через контекстное меню "играть в плейлисте" #172

Closed
sadr0b0t opened this issue Feb 23, 2023 · 4 comments
Labels
enhancement New feature or request

Comments

@sadr0b0t
Copy link
Owner

Переходим в экран плейлиста, выставляем настройки фильтра/сортировки, кликаем на ролике в списке и выбираем меню "играть в плейлисте".

На экране плеера:

  • открытый ролик должен быть не в начале списка, а в исходной позициив сотрированном/фильтрованном списке
  • список рекомендации следует промотать к этому ролику
  • кнопка "следующее видео" должна открывать ролик, следующий за открытым, а не первый в списке рекомендаций

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

Связанный тикет (там этот случай следует исключить): #170

Где не желательно: Меню "играть в плейлисте" на выбранном ролике в отсортированном/фильтрованном, т.к. в таком случае нарушится порядок сортировки. Для этого меню хороший вариант - загружать рекомендации с настройками сортировки/фильтра, а к выбранному ролику прокручивать список. Проблема здесь в том, что у него заранее неизвестен индекс в поисковой выдаче, но это решается ручным перебором. Мало вероятно, что ролик окажется в конце длинного списка, т.к. в таком случае пользователь должен был перемотать его вручную в гуе.

@sadr0b0t sadr0b0t added the enhancement New feature or request label Feb 23, 2023
@sadr0b0t
Copy link
Owner Author

Реализовал прокрутку через ручной перебор элементов в адаптере (коммита пока нет). Режим включен при открытии ролика через контекстное меню "играть в плейлисте" в публичном экарне плейлиста и при клике на ролик в экране плейлиста в настройках.

Если элемент плюс-минус в начале списка, работает. Если промотать плейлист дальше, то не работает, т.к. PagedListAdapter загружает ролики из базы данных не сразу, а порциями по мере прокрутки списка, и в адаптере после некоторого индекса по порядковому номеру можно получить только null.

Пока оставлю как есть. Возможные варианты сделать идеально:

  • программно прокручивать список дальше и дальше, чтобы нужные элементы появлялись в адаптере, пока не будет найден нужный элемент (довольно муторно, т.к. подгрузка будет происходить в фоне).
  • попробовать посмотреть, есть ли запрос SQL, который даст порядковый номер исхомого элемента в выдаче запроса - тогда адаптер не будет нужен
  • можно этот же номер взять в исходном списке на экране плейлиста
  • попробовать сразу прогружать все элементы в список до необходимого - настройка PagedList.Config.Builder().setPageSize при создании PagedListAdapter. Можно выставить размер страницы так, чтобы он заведомо включал элемент, до которого нужно прокрутить. Вопрос где брать размер страницы - можно тоже на странице со списком до того, как откроем плеер. Техника примерно та же, что и с предыдущим пунктом. Может быть не очень эффективно с точки зрения экономии памяти, но для фильтрованных плейлистов и при условии, что пользователь изначально не будет мотать слишком глубоко вниз, можно быть приемлемо.

@sadr0b0t
Copy link
Owner Author

Реализовал прокрутку через ручной перебор элементов в адаптере (коммита пока нет)

оставлю этот код здесь:

if (videoId != VideoItem.ID_NONE) {
                        playerService.playVideoItem(videoId, false);

                        if (WatchVideoActivity.this.getIntent().getBooleanExtra(PARAM_SCROLL_TO_IN_RECOMMENDATIONS, false)) {
                            recommendationsListener = new RecommendationsListener() {
                                @Override
                                public void onFirstItemLoaded(final VideoItem firstItem) {
                                    // попробуем промотать список рекомендаций до выбранного видео
                                    int pos = -1;

                                    // сейчас сюда попадаем только в одном случае - если ролик выбран в
                                    // публичном экране плейлиста через меню "играть в плейлисте" -
                                    // в этом случае у нас для рекомендаций будет создан VideoItemPagedListAdapter
                                    final VideoItemPagedListAdapter adapterAsPaged = (VideoItemPagedListAdapter) videoList.getAdapter();
                                    for (int i = 0; i < adapterAsPaged.getItemCount(); i++) {
                                        if (adapterAsPaged.getItem(i) == null) {
                                            // если в качестве элементов пошли null, значит
                                            // адаптер в этот заход не загрузил ролики до нужного;
                                            // найти индекс ролика в незагруженном списке будет
                                            // довольно проблематично, поэтому в этой ситуации сейчас
                                            // просто ничего не делаем
                                            break;
                                        } else if (adapterAsPaged.getItem(i).getId() == videoId) {
                                            pos = i;
                                            break;
                                        }
                                    }

                                    if (pos != -1) {
                                        playerService.getVideoListPosMap().put(videoId, pos);
                                        playerService.setVideoListCurrentPosition(pos);
                                        videoList.scrollToPosition(pos);
                                    }
                                }
                            };
                        } else {
                            recommendationsListener = new RecommendationsListener() {
                                @Override
                                public void onFirstItemLoaded(final VideoItem firstItem) {
                                    // проверим, совпадает ли первый элемент в рекомендациях с роликом,
                                    // который загружен; если совпадает, то установим индекс текущего ролика
                                    // нулём, чтобы плеер понимал, что загруженное видео - первое в списке
                                    // рекомендаций
                                    if (videoId == firstItem.getId()) {
                                        playerService.getVideoListPosMap().put(videoId, 0);
                                        playerService.setVideoListCurrentPosition(0);
                                    }
                                }
                            };
                        }
                    }

и реализую по этой схеме:

можно этот же номер взять в исходном списке на экране плейлиста

@sadr0b0t
Copy link
Owner Author

sadr0b0t commented Feb 23, 2023

можно этот же номер взять в исходном списке на экране плейлиста

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

Заодно получилось этим способом применить промотку к выбранному элементу при открытии ролика по адресу в списках "новое для всех плейлистов", "новое для плейлиста", "добавить плейлист", т.е. там, где списки берут не из базы данных. Но срабатывает не всегда, если умотать далеко вниз список.

@sadr0b0t
Copy link
Owner Author

Исправлено здесь 3d024dd в этом тикете #7

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant