Add day/week/month/year selector in the search.

This commit is contained in:
Saveliy Skresanov 2024-04-12 22:50:55 +07:00
parent efeac4fd8a
commit 0cfb91ce86
9 changed files with 114 additions and 10 deletions

View File

@ -14,4 +14,13 @@ namespace http
sortByVotes,
sortByDate,
};
enum Period
{
allSaves,
todaySaves,
weekSaves,
monthSaves,
yearSaves,
};
}

View File

@ -1,3 +1,4 @@
#include <ctime>
#include "SearchSavesRequest.h"
#include "Config.h"
#include "client/Client.h"
@ -6,7 +7,7 @@
namespace http
{
static ByteString Url(int start, int count, ByteString query, Sort sort, Category category)
static ByteString Url(int start, int count, ByteString query, Period period, Sort sort, Category category)
{
ByteStringBuilder builder;
builder << SCHEME << SERVER << "/Browse.json?Start=" << start << "&Count=" << count;
@ -17,6 +18,38 @@ namespace http
}
query += str;
};
time_t currentTime = time(NULL);
if(period)
{
switch (period)
{
case todaySaves:
currentTime -= 60*60*24; // One day
break;
case weekSaves:
currentTime -= 60*60*24*7; // One week
break;
case monthSaves:
currentTime -= 60*60*24*31; // One month
break;
case yearSaves:
currentTime -= 60*60*24*365; // One year
break;
default:
break;
}
struct tm currentTimeData = *localtime(&currentTime);
ByteStringBuilder afterQuery;
afterQuery << "after:" << currentTimeData.tm_year+1900 << "-" <<
(currentTimeData.tm_mon < 9 ? "0" : "") << currentTimeData.tm_mon+1 << "-" <<
(currentTimeData.tm_mday < 10 ? "0" : "") << currentTimeData.tm_mday;
appendToQuery(afterQuery.Build());
}
switch (sort)
{
case sortByDate:
@ -48,7 +81,7 @@ namespace http
return builder.Build();
}
SearchSavesRequest::SearchSavesRequest(int start, int count, ByteString query, Sort sort, Category category) : APIRequest(Url(start, count, query, sort, category), authUse, false)
SearchSavesRequest::SearchSavesRequest(int start, int count, ByteString query, Period period, Sort sort, Category category) : APIRequest(Url(start, count, query, period, sort, category), authUse, false)
{
}

View File

@ -8,7 +8,7 @@ namespace http
class SearchSavesRequest : public APIRequest
{
public:
SearchSavesRequest(int start, int count, ByteString query, Sort sort, Category category);
SearchSavesRequest(int start, int count, ByteString query, Period period, Sort sort, Category category);
std::pair<int, std::vector<std::unique_ptr<SaveInfo>>> Finish();
};

View File

@ -136,6 +136,32 @@ void SearchController::SetPageRelative(int offset)
searchModel->UpdateSaveList(page, searchModel->GetLastQuery());
}
void SearchController::ChangePeriod(int period)
{
switch(period)
{
case 0:
searchModel->SetPeriod(http::allSaves);
break;
case 1:
searchModel->SetPeriod(http::todaySaves);
break;
case 2:
searchModel->SetPeriod(http::weekSaves);
break;
case 3:
searchModel->SetPeriod(http::monthSaves);
break;
case 4:
searchModel->SetPeriod(http::yearSaves);
break;
default:
searchModel->SetPeriod(http::allSaves);
}
searchModel->UpdateSaveList(1, searchModel->GetLastQuery());
}
void SearchController::ChangeSort()
{
if(searchModel->GetSort() == http::sortByDate)

View File

@ -37,6 +37,7 @@ public:
void Refresh();
void SetPage(int page);
void SetPageRelative(int offset);
void ChangePeriod(int period);
void ChangeSort();
void ShowOwn(bool show);
void ShowFavourite(bool show);

View File

@ -11,6 +11,7 @@
#include <cmath>
SearchModel::SearchModel():
currentPeriod(http::allSaves),
currentSort(http::sortByVotes),
currentPage(1),
resultCount(0),
@ -30,11 +31,11 @@ bool SearchModel::GetShowTags()
return showTags;
}
void SearchModel::BeginSearchSaves(int start, int count, String query, http::Sort sort, http::Category category)
void SearchModel::BeginSearchSaves(int start, int count, String query, http::Period period, http::Sort sort, http::Category category)
{
lastError = "";
resultCount = 0;
searchSaves = std::make_unique<http::SearchSavesRequest>(start, count, query.ToUtf8(), sort, category);
searchSaves = std::make_unique<http::SearchSavesRequest>(start, count, query.ToUtf8(), period, sort, category);
searchSaves->Start();
}
@ -95,7 +96,7 @@ bool SearchModel::UpdateSaveList(int pageNumber, String query)
//resultCount = 0;
currentPage = pageNumber;
if(pageNumber == 1 && !showOwn && !showFavourite && currentSort == http::sortByVotes && query == "")
if(pageNumber == 1 && !showOwn && !showFavourite && currentPeriod == http::allSaves && currentSort == http::sortByVotes && query == "")
SetShowTags(true);
else
SetShowTags(false);
@ -120,7 +121,7 @@ bool SearchModel::UpdateSaveList(int pageNumber, String query)
{
category = http::categoryMyOwn;
}
BeginSearchSaves((currentPage-1)*20, 20, lastQuery, currentSort, category);
BeginSearchSaves((currentPage-1)*20, 20, lastQuery, currentPeriod, currentSort, category);
return true;
}
return false;
@ -178,6 +179,7 @@ void SearchModel::AddObserver(SearchView * observer)
observers.push_back(observer);
observer->NotifySaveListChanged(this);
observer->NotifyPageChanged(this);
observer->NotifyPeriodChanged(this);
observer->NotifySortChanged(this);
observer->NotifyShowOwnChanged(this);
observer->NotifyTagListChanged(this);
@ -258,6 +260,15 @@ void SearchModel::notifyPageChanged()
}
}
void SearchModel::notifyPeriodChanged()
{
for (size_t i = 0; i < observers.size(); i++)
{
SearchView* cObserver = observers[i];
cObserver->NotifyPeriodChanged(this);
}
}
void SearchModel::notifySortChanged()
{
for (size_t i = 0; i < observers.size(); i++)
@ -296,7 +307,7 @@ void SearchModel::notifySelectedChanged()
int SearchModel::GetPageCount()
{
if (!showOwn && !showFavourite && currentSort == http::sortByVotes && lastQuery == "")
if (!showOwn && !showFavourite && currentPeriod == http::allSaves && currentSort == http::sortByVotes && lastQuery == "")
return std::max(1, (int)(ceil(resultCount/20.0f))+1); //add one for front page (front page saves are repeated twice)
else
return std::max(1, (int)(ceil(resultCount/20.0f)));

View File

@ -18,7 +18,7 @@ class SearchModel
{
private:
std::unique_ptr<http::SearchSavesRequest> searchSaves;
void BeginSearchSaves(int start, int count, String query, http::Sort sort, http::Category category);
void BeginSearchSaves(int start, int count, String query, http::Period period, http::Sort sort, http::Category category);
std::vector<std::unique_ptr<SaveInfo>> EndSearchSaves();
void BeginGetTags(int start, int count, String query);
@ -26,6 +26,7 @@ private:
std::unique_ptr<http::SearchTagsRequest> getTags;
std::unique_ptr<SaveInfo> loadedSave;
http::Period currentPeriod;
http::Sort currentSort;
String lastQuery;
String lastError;
@ -42,6 +43,7 @@ private:
void notifyTagListChanged();
void notifySelectedChanged();
void notifyPageChanged();
void notifyPeriodChanged();
void notifySortChanged();
void notifyShowOwnChanged();
void notifyShowFavouriteChanged();
@ -61,6 +63,8 @@ public:
int GetPageCount();
int GetPageNum() { return currentPage; }
String GetLastQuery() { return lastQuery; }
void SetPeriod(http::Period period) { if(!searchSaves) { currentPeriod = period; } notifyPeriodChanged(); }
http::Period GetPeriod() { return currentPeriod; }
void SetSort(http::Sort sort) { if(!searchSaves) { currentSort = sort; } notifySortChanged(); }
http::Sort GetSort() { return currentSort; }
void SetShowOwn(bool show) { if(!searchSaves) { if(show!=showOwn) { showOwn = show; } } notifyShowOwnChanged(); }

View File

@ -9,6 +9,7 @@
#include "gui/interface/RichLabel.h"
#include "gui/interface/Textbox.h"
#include "gui/interface/Spinner.h"
#include "gui/interface/DropDown.h"
#include "PowderToySDL.h"
#include "graphics/Graphics.h"
#include "SimulationConfig.h"
@ -43,7 +44,7 @@ SearchView::SearchView():
AddComponent(pageCountLabel);
AddComponent(pageTextbox);
searchField = new ui::Textbox(ui::Point(60, 10), ui::Point(WINDOWW-238, 17), "", "[search]");
searchField = new ui::Textbox(ui::Point(60, 10), ui::Point(WINDOWW-283, 17), "", "[search]");
searchField->Appearance.icon = IconSearch;
searchField->Appearance.HorizontalAlign = ui::Appearance::AlignLeft;
searchField->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
@ -51,6 +52,17 @@ SearchView::SearchView():
searchField->SetLimit(100);
FocusComponent(searchField);
dateRange = new ui::DropDown(ui::Point(WINDOWW-185, 10), ui::Point(36, 17));
dateRange->SetActionCallback({ [this] { c->ChangePeriod(dateRange->GetOption().second); } });
dateRange->AddOption({"All", 0});
dateRange->AddOption({"Day", 1});
dateRange->AddOption({"Week", 2});
dateRange->AddOption({"Month", 3});
dateRange->AddOption({"Year", 4});
dateRange->Appearance.HorizontalAlign = ui::Appearance::AlignCentre;
dateRange->Appearance.VerticalAlign = ui::Appearance::AlignMiddle;
AddComponent(dateRange);
sortButton = new ui::Button(ui::Point(WINDOWW-140, 10), ui::Point(61, 17), "Sort");
sortButton->SetIcon(IconVoteSort);
sortButton->SetTogglable(true);
@ -202,6 +214,11 @@ void SearchView::Search(String query)
c->DoSearch(query, true);
}
void SearchView::NotifyPeriodChanged(SearchModel * sender)
{
dateRange->SetOption(sender->GetPeriod());
}
void SearchView::NotifySortChanged(SearchModel * sender)
{
if(sender->GetSort() == http::sortByVotes)

View File

@ -11,6 +11,7 @@ namespace ui
class Label;
class Spinner;
class Textbox;
class DropDown;
}
class SearchModel;
@ -32,6 +33,7 @@ private:
ui::Label * pageCountLabel;
ui::Label * tagsLabel;
ui::RichLabel * motdLabel = nullptr;
ui::DropDown * dateRange;
ui::Button * sortButton;
ui::Button * ownButton;
ui::Spinner * loadingSpinner;
@ -52,6 +54,7 @@ public:
void NotifySaveListChanged(SearchModel * sender);
void NotifySelectedChanged(SearchModel * sender);
void NotifyPageChanged(SearchModel * sender);
void NotifyPeriodChanged(SearchModel * sender);
void NotifySortChanged(SearchModel * sender);
void NotifyShowOwnChanged(SearchModel * sender);
void NotifyShowFavouriteChanged(SearchModel * sender);