sadr0b0t / yashlang

PeerTube and YouTube player for Android with local playlists and whitelisted recommendations
GNU General Public License v3.0
52 stars 3 forks source link

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

Closed sadr0b0t closed 1 year ago

sadr0b0t commented 1 year ago

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

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

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

Связанный тикет (там этот случай следует исключить): https://github.com/sadr0b0t/yashlang/issues/170

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

sadr0b0t commented 1 year ago

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

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

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

sadr0b0t commented 1 year ago

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

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

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 commented 1 year ago

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

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

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

sadr0b0t commented 1 year ago

Исправлено здесь https://github.com/sadr0b0t/yashlang/commit/3d024dd44d7ab39f641b1db13327315ae5c7b985 в этом тикете https://github.com/sadr0b0t/yashlang/issues/7