1 #include "SearchController.h"
2
3 #include "SearchModel.h"
4 #include "SearchView.h"
5
6 #include "gui/dialogues/ConfirmPrompt.h"
7 #include "gui/preview/PreviewController.h"
8 #include "gui/preview/PreviewView.h"
9
10 #include "tasks/Task.h"
11 #include "tasks/TaskWindow.h"
12
13 #include "Platform.h"
14 #include "Controller.h"
15
16 #include "graphics/Graphics.h"
17
18 #include "client/Client.h"
19
20 #include "common/tpt-minmax.h"
21
SearchController(std::function<void ()> onDone_)22 SearchController::SearchController(std::function<void ()> onDone_):
23 activePreview(NULL),
24 nextQueryTime(0.0f),
25 nextQueryDone(true),
26 instantOpen(false),
27 doRefresh(false),
28 HasExited(false)
29 {
30 searchModel = new SearchModel();
31 searchView = new SearchView();
32 searchModel->AddObserver(searchView);
33 searchView->AttachController(this);
34
35 searchModel->UpdateSaveList(1, "");
36
37 onDone = onDone_;
38 }
39
GetLoadedSave()40 SaveInfo * SearchController::GetLoadedSave()
41 {
42 return searchModel->GetLoadedSave();
43 }
44
ReleaseLoadedSave()45 void SearchController::ReleaseLoadedSave()
46 {
47 searchModel->SetLoadedSave(NULL);
48 }
49
Update()50 void SearchController::Update()
51 {
52 if (doRefresh)
53 {
54 if (searchModel->UpdateSaveList(searchModel->GetPageNum(), searchModel->GetLastQuery()))
55 {
56 nextQueryDone = true;
57 doRefresh = false;
58 }
59 }
60 else if (!nextQueryDone && nextQueryTime < Platform::GetTime())
61 {
62 if (searchModel->UpdateSaveList(1, nextQuery))
63 nextQueryDone = true;
64 }
65 searchModel->Update();
66 if(activePreview && activePreview->HasExited)
67 {
68 delete activePreview;
69 activePreview = NULL;
70 if(searchModel->GetLoadedSave())
71 {
72 Exit();
73 }
74 }
75 }
76
Exit()77 void SearchController::Exit()
78 {
79 InstantOpen(false);
80 searchView->CloseActiveWindow();
81 if (onDone)
82 onDone();
83 //HasExited = true;
84 }
85
~SearchController()86 SearchController::~SearchController()
87 {
88 delete activePreview;
89 searchView->CloseActiveWindow();
90 delete searchModel;
91 delete searchView;
92 }
93
DoSearch(String query,bool now)94 void SearchController::DoSearch(String query, bool now)
95 {
96 nextQuery = query;
97 if (!now)
98 {
99 nextQueryTime = Platform::GetTime()+600;
100 nextQueryDone = false;
101 }
102 else
103 {
104 nextQueryDone = searchModel->UpdateSaveList(1, nextQuery);
105 }
106 }
107
DoSearch2(String query)108 void SearchController::DoSearch2(String query)
109 {
110 // calls SearchView function to set textbox text, then calls DoSearch
111 searchView->Search(query);
112 }
113
Refresh()114 void SearchController::Refresh()
115 {
116 doRefresh = true;
117 }
118
SetPage(int page)119 void SearchController::SetPage(int page)
120 {
121 if (page != searchModel->GetPageNum() && page > 0 && page <= searchModel->GetPageCount())
122 searchModel->UpdateSaveList(page, searchModel->GetLastQuery());
123 }
124
SetPageRelative(int offset)125 void SearchController::SetPageRelative(int offset)
126 {
127 int page = std::min(std::max(searchModel->GetPageNum() + offset, 1), searchModel->GetPageCount());
128 if (page != searchModel->GetPageNum())
129 searchModel->UpdateSaveList(page, searchModel->GetLastQuery());
130 }
131
ChangeSort()132 void SearchController::ChangeSort()
133 {
134 if(searchModel->GetSort() == "new")
135 {
136 searchModel->SetSort("best");
137 }
138 else
139 {
140 searchModel->SetSort("new");
141 }
142 searchModel->UpdateSaveList(1, searchModel->GetLastQuery());
143 }
144
ShowOwn(bool show)145 void SearchController::ShowOwn(bool show)
146 {
147 if(Client::Ref().GetAuthUser().UserID)
148 {
149 searchModel->SetShowFavourite(false);
150 searchModel->SetShowOwn(show);
151 }
152 else
153 searchModel->SetShowOwn(false);
154 searchModel->UpdateSaveList(1, searchModel->GetLastQuery());
155 }
156
ShowFavourite(bool show)157 void SearchController::ShowFavourite(bool show)
158 {
159 if(Client::Ref().GetAuthUser().UserID)
160 {
161 searchModel->SetShowOwn(false);
162 searchModel->SetShowFavourite(show);
163 }
164 else
165 searchModel->SetShowFavourite(false);
166 searchModel->UpdateSaveList(1, searchModel->GetLastQuery());
167 }
168
Selected(int saveID,bool selected)169 void SearchController::Selected(int saveID, bool selected)
170 {
171 if(!Client::Ref().GetAuthUser().UserID)
172 return;
173
174 if(selected)
175 searchModel->SelectSave(saveID);
176 else
177 searchModel->DeselectSave(saveID);
178 }
179
InstantOpen(bool instant)180 void SearchController::InstantOpen(bool instant)
181 {
182 instantOpen = instant;
183 }
184
OpenSaveDone()185 void SearchController::OpenSaveDone()
186 {
187 if (activePreview->GetDoOpen() && activePreview->GetSaveInfo())
188 {
189 searchModel->SetLoadedSave(activePreview->GetSaveInfo());
190 }
191 else
192 {
193 searchModel->SetLoadedSave(NULL);
194 }
195 }
196
OpenSave(int saveID)197 void SearchController::OpenSave(int saveID)
198 {
199 delete activePreview;
200 Graphics * g = searchView->GetGraphics();
201 g->fillrect(XRES/3, WINDOWH-20, XRES/3, 20, 0, 0, 0, 150); //dim the "Page X of Y" a little to make the CopyTextButton more noticeable
202 activePreview = new PreviewController(saveID, 0, instantOpen, [this] { OpenSaveDone(); });
203 activePreview->GetView()->MakeActiveWindow();
204 }
205
OpenSave(int saveID,int saveDate)206 void SearchController::OpenSave(int saveID, int saveDate)
207 {
208 delete activePreview;
209 Graphics * g = searchView->GetGraphics();
210 g->fillrect(XRES/3, WINDOWH-20, XRES/3, 20, 0, 0, 0, 150); //dim the "Page X of Y" a little to make the CopyTextButton more noticeable
211 activePreview = new PreviewController(saveID, saveDate, instantOpen, [this] { OpenSaveDone(); });
212 activePreview->GetView()->MakeActiveWindow();
213 }
214
ClearSelection()215 void SearchController::ClearSelection()
216 {
217 searchModel->ClearSelected();
218 }
219
RemoveSelected()220 void SearchController::RemoveSelected()
221 {
222 StringBuilder desc;
223 desc << "Are you sure you want to delete " << searchModel->GetSelected().size() << " save";
224 if(searchModel->GetSelected().size()>1)
225 desc << "s";
226 desc << "?";
227 new ConfirmPrompt("Delete saves", desc.Build(), { [this] {
228 removeSelectedC();
229 } });
230 }
231
removeSelectedC()232 void SearchController::removeSelectedC()
233 {
234 class RemoveSavesTask : public Task
235 {
236 SearchController *c;
237 std::vector<int> saves;
238 public:
239 RemoveSavesTask(std::vector<int> saves_, SearchController *c_) { saves = saves_; c = c_; }
240 bool doWork() override
241 {
242 for (size_t i = 0; i < saves.size(); i++)
243 {
244 notifyStatus(String::Build("Deleting save [", saves[i], "] ..."));
245 if (Client::Ref().DeleteSave(saves[i])!=RequestOkay)
246 {
247 notifyError(String::Build("Failed to delete [", saves[i], "]: ", Client::Ref().GetLastError()));
248 c->Refresh();
249 return false;
250 }
251 notifyProgress((float(i+1)/float(saves.size())*100));
252 }
253 c->Refresh();
254 return true;
255 }
256 };
257
258 std::vector<int> selected = searchModel->GetSelected();
259 new TaskWindow("Removing saves", new RemoveSavesTask(selected, this));
260 ClearSelection();
261 searchModel->UpdateSaveList(searchModel->GetPageNum(), searchModel->GetLastQuery());
262 }
263
UnpublishSelected(bool publish)264 void SearchController::UnpublishSelected(bool publish)
265 {
266 StringBuilder desc;
267 desc << "Are you sure you want to " << (publish ? String("publish ") : String("unpublish ")) << searchModel->GetSelected().size() << " save";
268 if (searchModel->GetSelected().size() > 1)
269 desc << "s";
270 desc << "?";
271 new ConfirmPrompt(publish ? String("Publish Saves") : String("Unpublish Saves"), desc.Build(), { [this, publish] {
272 unpublishSelectedC(publish);
273 } });
274 }
275
unpublishSelectedC(bool publish)276 void SearchController::unpublishSelectedC(bool publish)
277 {
278 class UnpublishSavesTask : public Task
279 {
280 std::vector<int> saves;
281 SearchController *c;
282 bool publish;
283 public:
284 UnpublishSavesTask(std::vector<int> saves_, SearchController *c_, bool publish_) { saves = saves_; c = c_; publish = publish_; }
285
286 bool PublishSave(int saveID)
287 {
288 notifyStatus(String::Build("Publishing save [", saveID, "]"));
289 if (Client::Ref().PublishSave(saveID) != RequestOkay)
290 return false;
291 return true;
292 }
293
294 bool UnpublishSave(int saveID)
295 {
296 notifyStatus(String::Build("Unpublishing save [", saveID, "]"));
297 if (Client::Ref().UnpublishSave(saveID) != RequestOkay)
298 return false;
299 return true;
300 }
301
302 bool doWork() override
303 {
304 bool ret;
305 for (size_t i = 0; i < saves.size(); i++)
306 {
307 if (publish)
308 ret = PublishSave(saves[i]);
309 else
310 ret = UnpublishSave(saves[i]);
311 if (!ret)
312 {
313 if (publish) // uses html page so error message will be spam
314 notifyError(String::Build("Failed to publish [", saves[i], "], is this save yours?"));
315 else
316 notifyError(String::Build("Failed to unpublish [", saves[i], "]: " + Client::Ref().GetLastError()));
317 c->Refresh();
318 return false;
319 }
320 notifyProgress((float(i+1)/float(saves.size())*100));
321 }
322 c->Refresh();
323 return true;
324 }
325 };
326
327 std::vector<int> selected = searchModel->GetSelected();
328 new TaskWindow(publish ? String("Publishing Saves") : String("Unpublishing Saves"), new UnpublishSavesTask(selected, this, publish));
329 }
330
FavouriteSelected()331 void SearchController::FavouriteSelected()
332 {
333 class FavouriteSavesTask : public Task
334 {
335 std::vector<int> saves;
336 public:
337 FavouriteSavesTask(std::vector<int> saves_) { saves = saves_; }
338 bool doWork() override
339 {
340 for (size_t i = 0; i < saves.size(); i++)
341 {
342 notifyStatus(String::Build("Favouring save [", saves[i], "]"));
343 if (Client::Ref().FavouriteSave(saves[i], true)!=RequestOkay)
344 {
345 notifyError(String::Build("Failed to favourite [", saves[i], "]: " + Client::Ref().GetLastError()));
346 return false;
347 }
348 notifyProgress((float(i+1)/float(saves.size())*100));
349 }
350 return true;
351 }
352 };
353
354 class UnfavouriteSavesTask : public Task
355 {
356 std::vector<int> saves;
357 public:
358 UnfavouriteSavesTask(std::vector<int> saves_) { saves = saves_; }
359 bool doWork() override
360 {
361 for (size_t i = 0; i < saves.size(); i++)
362 {
363 notifyStatus(String::Build("Unfavouring save [", saves[i], "]"));
364 if (Client::Ref().FavouriteSave(saves[i], false)!=RequestOkay)
365 {
366 notifyError(String::Build("Failed to unfavourite [", saves[i], "]: " + Client::Ref().GetLastError()));
367 return false;
368 }
369 notifyProgress((float(i+1)/float(saves.size())*100));
370 }
371 return true;
372 }
373 };
374
375 std::vector<int> selected = searchModel->GetSelected();
376 if (!searchModel->GetShowFavourite())
377 new TaskWindow("Favouring saves", new FavouriteSavesTask(selected));
378 else
379 new TaskWindow("Unfavouring saves", new UnfavouriteSavesTask(selected));
380 ClearSelection();
381 }
382