]> git.sur5r.net Git - minitube/blob - src/standardfeedsview.cpp
Upload 3.9.3-2 to unstable
[minitube] / src / standardfeedsview.cpp
1 /* $BEGIN_LICENSE
2
3 This file is part of Minitube.
4 Copyright 2009, Flavio Tordini <flavio.tordini@gmail.com>
5
6 Minitube is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Minitube is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Minitube.  If not, see <http://www.gnu.org/licenses/>.
18
19 $END_LICENSE */
20
21 #include "standardfeedsview.h"
22 #include "mainwindow.h"
23 #include "painterutils.h"
24 #include "videosourcewidget.h"
25 #include "ytcategories.h"
26 #include "ytregions.h"
27 #include "ytstandardfeed.h"
28
29 #include "ivvideolist.h"
30 #include "videoapi.h"
31
32 #include "ytjstrending.h"
33
34 StandardFeedsView::StandardFeedsView(QWidget *parent) : View(parent), layout(0) {
35     setBackgroundRole(QPalette::Base);
36     setAutoFillBackground(true);
37
38     connect(MainWindow::instance()->getAction("worldwideRegion"), SIGNAL(triggered()),
39             SLOT(selectWorldwideRegion()));
40
41     connect(MainWindow::instance()->getAction("localRegion"), SIGNAL(triggered()),
42             SLOT(selectLocalRegion()));
43 }
44
45 void StandardFeedsView::load() {
46     setUpdatesEnabled(false);
47     resetLayout();
48
49     YTRegion region = YTRegions::currentRegion();
50
51     // TODO consolidate in YT
52     if (VideoAPI::impl() == VideoAPI::YT3) {
53         YTCategories *youTubeCategories = new YTCategories(this);
54         connect(youTubeCategories, SIGNAL(categoriesLoaded(const QVector<YTCategory> &)),
55                 SLOT(layoutCategories(const QVector<YTCategory> &)));
56         youTubeCategories->loadCategories();
57         addVideoSourceWidget(buildStandardFeed("most_popular", tr("Most Popular")));
58     } else if (VideoAPI::impl() == VideoAPI::JS) {
59         const QMap<QString, QString> pages = {{"default", tr("Trending")},
60                                               {"music", tr("Music")},
61                                               {"movies", tr("Movies")},
62                                               {"gaming", tr("Gaming")}};
63         auto i = pages.constBegin();
64         while (i != pages.constEnd()) {
65             addVideoSourceWidget(
66                     new YTJSTrending(i.value(), {{"page", i.key()}, {"geoLocation", region.id}}));
67             ++i;
68         }
69
70         setUpdatesEnabled(true);
71     } else {
72         QString regionParam = "region=" + region.id;
73         addVideoSourceWidget(new IVVideoList("popular?" + regionParam, tr("Most Popular")));
74         addVideoSourceWidget(new IVVideoList("trending?" + regionParam, tr("Trending")));
75         addVideoSourceWidget(new IVVideoList("trending?type=music&" + regionParam, tr("Music")));
76         addVideoSourceWidget(new IVVideoList("trending?type=news&" + regionParam, tr("News")));
77         addVideoSourceWidget(new IVVideoList("trending?type=movies&" + regionParam, tr("Movies")));
78         addVideoSourceWidget(new IVVideoList("trending?type=gaming&" + regionParam, tr("Gaming")));
79         setUpdatesEnabled(true);
80     }
81
82     QAction *regionAction = MainWindow::instance()->getRegionAction();
83     regionAction->setText(region.name);
84     regionAction->setIcon(YTRegions::iconForRegionId(region.id));
85
86     loadNextPreview();
87 }
88
89 void StandardFeedsView::loadNextPreview(VideoSourceWidget *previous) {
90     int index = 0;
91     if (previous) {
92         index = sourceWidgets.indexOf(previous);
93         index++;
94         if (index == sourceWidgets.length() || index < 0) return;
95     }
96     auto w = sourceWidgets.at(index);
97     w->loadPreview()->finally([this, w] { loadNextPreview(w); });
98 }
99
100 void StandardFeedsView::layoutCategories(const QVector<YTCategory> &categories) {
101     QString regionId = YTRegions::currentRegionId();
102     for (const YTCategory &category : categories) {
103         // assign a parent to this VideoSource  so it won't be deleted by MediaView
104         YTStandardFeed *feed = new YTStandardFeed(this);
105         feed->setCategory(category.term);
106         feed->setLabel(category.label);
107         feed->setRegionId(regionId);
108         feed->setFeedId("most_popular");
109         addVideoSourceWidget(feed);
110     }
111     if (categories.size() > 1) setUpdatesEnabled(true);
112 }
113
114 void StandardFeedsView::addVideoSourceWidget(VideoSource *videoSource) {
115     VideoSourceWidget *w = new VideoSourceWidget(videoSource);
116     connect(w, SIGNAL(activated(VideoSource *)), SIGNAL(activated(VideoSource *)));
117     connect(w, SIGNAL(unavailable(VideoSourceWidget *)),
118             SLOT(removeVideoSourceWidget(VideoSourceWidget *)));
119     int i = layout->count();
120     const int cols = VideoAPI::impl() == VideoAPI::YT3 ? 5 : 2;
121     layout->addWidget(w, i / cols, i % cols);
122
123     connect(w, &QObject::destroyed, this, [this, w] { sourceWidgets.removeOne(w); });
124     sourceWidgets << w;
125 }
126
127 void StandardFeedsView::removeVideoSourceWidget(VideoSourceWidget *videoSourceWidget) {
128     qDebug() << videoSourceWidget->getVideoSource()->getName();
129     layout->removeWidget(videoSourceWidget);
130     videoSourceWidget->deleteLater();
131
132     const int layoutCount = layout->count();
133     QVector<QLayoutItem *> items;
134     items.reserve(layoutCount);
135
136     for (int i = layoutCount - 1; i >= 0; i--) {
137         QLayoutItem *item = layout->takeAt(i);
138         if (item && item->widget()) items.append(item);
139     }
140
141     const int itemCount = items.size();
142     const int cols = 2; // itemCount / 3;
143     for (int i = itemCount - 1; i >= 0; i--) {
144         QLayoutItem *item = items.at(i);
145         int index = itemCount - 1 - i;
146         layout->addItem(item, index / cols, index % cols);
147     }
148 }
149
150 void StandardFeedsView::resetLayout() {
151     if (layout) {
152         while (QLayoutItem *item = layout->takeAt(0)) {
153             delete item->widget();
154             delete item;
155         }
156         delete layout;
157     }
158
159     layout = new QGridLayout(this);
160     layout->setMargin(0);
161     layout->setSpacing(0);
162 }
163
164 YTStandardFeed *
165 StandardFeedsView::buildStandardFeed(const QString &feedId, const QString &label, QString time) {
166     YTStandardFeed *feed = new YTStandardFeed(this);
167     feed->setFeedId(feedId);
168     feed->setLabel(label);
169     if (!time.isEmpty()) feed->setTime(time);
170     feed->setRegionId(YTRegions::currentRegionId());
171     return feed;
172 }
173
174 void StandardFeedsView::appear() {
175     if (!layout) {
176         update();
177         qApp->processEvents();
178         load();
179     }
180     QAction *regionAction = MainWindow::instance()->getRegionAction();
181     MainWindow::instance()->showActionsInStatusBar({regionAction}, true);
182 }
183
184 void StandardFeedsView::disappear() {
185     QAction *regionAction = MainWindow::instance()->getRegionAction();
186     MainWindow::instance()->showActionsInStatusBar({regionAction}, false);
187 }
188
189 void StandardFeedsView::selectWorldwideRegion() {
190     YTRegions::setRegion(YTRegions::defaultRegion().id);
191     load();
192 }
193
194 void StandardFeedsView::selectLocalRegion() {
195     YTRegions::setRegion(YTRegions::localRegion().id);
196     load();
197 }
198
199 void StandardFeedsView::paintEvent(QPaintEvent *event) {
200     QWidget::paintEvent(event);
201 }