HaikuDepot: Increment Pkg View Counter
Closes #16814 Change-Id: Idf451628b4680fb33563dbf4817bd11049c326b5 Reviewed-on: https://review.haiku-os.org/c/haiku/+/3803 Reviewed-by: Jérôme Duval <jerome.duval@gmail.com>
This commit is contained in:
parent
068d41df0f
commit
133ebab62c
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018-2020, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* Copyright 2018-2021, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef HAIKU_DEPOT_CONSTANTS_H
|
||||
@ -73,6 +73,15 @@ enum BitmapSize {
|
||||
#define KEY_MAIN_SETTINGS "main_settings"
|
||||
|
||||
|
||||
#define SETTING_SHOW_AVAILABLE_PACKAGES "show available packages"
|
||||
#define SETTING_SHOW_INSTALLED_PACKAGES "show installed packages"
|
||||
#define SETTING_SHOW_DEVELOP_PACKAGES "show develop packages"
|
||||
#define SETTING_SHOW_SOURCE_PACKAGES "show source packages"
|
||||
#define SETTING_CAN_SHARE_ANONYMOUS_USER_DATA "can share anonymous usage data"
|
||||
#define SETTING_PACKAGE_LIST_VIEW_MODE "packageListViewMode"
|
||||
// unfortunately historical difference in casing.
|
||||
|
||||
|
||||
// These constants reference resources in 'HaikuDepot.ref'
|
||||
enum {
|
||||
RSRC_STAR_BLUE = 510,
|
||||
|
@ -120,6 +120,7 @@ local applicationSources =
|
||||
FeaturedPackagesView.cpp
|
||||
FilterView.cpp
|
||||
IconTarPtr.cpp
|
||||
IncrementViewCounterProcess.cpp
|
||||
JobStateListener.cpp
|
||||
LanguageModel.cpp
|
||||
LinkView.cpp
|
||||
@ -146,6 +147,7 @@ local applicationSources =
|
||||
support.cpp
|
||||
ScreenshotWindow.cpp
|
||||
ScrollableGroupView.cpp
|
||||
SettingsWindow.cpp
|
||||
SharedBitmap.cpp
|
||||
ToLatestUserUsageConditionsWindow.cpp
|
||||
UserCredentials.cpp
|
||||
|
@ -212,7 +212,8 @@ Model::Model()
|
||||
fShowAvailablePackages(true),
|
||||
fShowInstalledPackages(true),
|
||||
fShowSourcePackages(false),
|
||||
fShowDevelopPackages(false)
|
||||
fShowDevelopPackages(false),
|
||||
fCanShareAnonymousUsageData(false)
|
||||
{
|
||||
}
|
||||
|
||||
@ -436,6 +437,13 @@ Model::SetPackageListViewMode(package_list_view_mode mode)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Model::SetCanShareAnonymousUsageData(bool value)
|
||||
{
|
||||
fCanShareAnonymousUsageData = value;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Model::SetShowAvailablePackages(bool show)
|
||||
{
|
||||
|
@ -129,6 +129,9 @@ public:
|
||||
void SetShowDevelopPackages(bool show);
|
||||
bool ShowDevelopPackages() const
|
||||
{ return fShowDevelopPackages; }
|
||||
void SetCanShareAnonymousUsageData(bool value);
|
||||
bool CanShareAnonymousUsageData() const
|
||||
{ return fCanShareAnonymousUsageData; }
|
||||
|
||||
// Retrieve package information
|
||||
static const uint32 POPULATE_CACHED_RATING = 1 << 0;
|
||||
@ -150,8 +153,8 @@ public:
|
||||
const BString& passwordClear,
|
||||
bool storePassword);
|
||||
|
||||
const WebAppInterface&
|
||||
GetWebAppInterface() const
|
||||
WebAppInterface&
|
||||
GetWebAppInterface()
|
||||
{ return fWebAppInterface; }
|
||||
|
||||
status_t IconTarPath(BPath& path) const;
|
||||
@ -205,6 +208,7 @@ private:
|
||||
bool fShowInstalledPackages;
|
||||
bool fShowSourcePackages;
|
||||
bool fShowDevelopPackages;
|
||||
bool fCanShareAnonymousUsageData;
|
||||
|
||||
LanguageModel fLanguageModel;
|
||||
PackageIconTarRepository
|
||||
|
@ -453,6 +453,7 @@ PackageInfo::PackageInfo()
|
||||
fFileName(),
|
||||
fSize(0),
|
||||
fDepotName(""),
|
||||
fViewed(false),
|
||||
fIsCollatingChanges(false),
|
||||
fCollatedChanges(0)
|
||||
{
|
||||
@ -483,6 +484,7 @@ PackageInfo::PackageInfo(const BPackageInfo& info)
|
||||
fFileName(info.FileName()),
|
||||
fSize(0), // TODO: Retrieve local file size
|
||||
fDepotName(""),
|
||||
fViewed(false),
|
||||
fIsCollatingChanges(false),
|
||||
fCollatedChanges(0)
|
||||
{
|
||||
@ -529,6 +531,7 @@ PackageInfo::PackageInfo(const BString& name,
|
||||
fFileName(),
|
||||
fSize(0),
|
||||
fDepotName(""),
|
||||
fViewed(false),
|
||||
fIsCollatingChanges(false),
|
||||
fCollatedChanges(0)
|
||||
{
|
||||
@ -561,6 +564,7 @@ PackageInfo::PackageInfo(const PackageInfo& other)
|
||||
fFileName(other.fFileName),
|
||||
fSize(other.fSize),
|
||||
fDepotName(other.fDepotName),
|
||||
fViewed(other.fViewed),
|
||||
fIsCollatingChanges(false),
|
||||
fCollatedChanges(0)
|
||||
{
|
||||
@ -593,6 +597,8 @@ PackageInfo::operator=(const PackageInfo& other)
|
||||
fLocalFilePath = other.fLocalFilePath;
|
||||
fFileName = other.fFileName;
|
||||
fSize = other.fSize;
|
||||
fDepotName = other.fDepotName;
|
||||
fViewed = other.fViewed;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@ -987,6 +993,13 @@ PackageInfo::SetSize(int64 size)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageInfo::SetViewed()
|
||||
{
|
||||
fViewed = true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PackageInfo::SetDepotName(const BString& depotName)
|
||||
{
|
||||
|
@ -253,7 +253,8 @@ public:
|
||||
{ return fName; }
|
||||
void SetTitle(const BString& title);
|
||||
const BString& Title() const;
|
||||
const BPackageVersion& Version() const
|
||||
const BPackageVersion&
|
||||
Version() const
|
||||
{ return fVersion; }
|
||||
void SetShortDescription(const BString& description);
|
||||
const BString& ShortDescription() const
|
||||
@ -336,6 +337,10 @@ public:
|
||||
int64 Size() const
|
||||
{ return fSize; }
|
||||
|
||||
void SetViewed();
|
||||
bool Viewed() const
|
||||
{ return fViewed; }
|
||||
|
||||
void SetDepotName(const BString& depotName);
|
||||
const BString& DepotName() const
|
||||
{ return fDepotName; }
|
||||
@ -387,6 +392,7 @@ private:
|
||||
BString fFileName;
|
||||
int64 fSize;
|
||||
BString fDepotName;
|
||||
bool fViewed;
|
||||
|
||||
bool fIsCollatingChanges;
|
||||
uint32 fCollatedChanges;
|
||||
|
119
src/apps/haikudepot/server/IncrementViewCounterProcess.cpp
Normal file
119
src/apps/haikudepot/server/IncrementViewCounterProcess.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2021, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#include "IncrementViewCounterProcess.h"
|
||||
|
||||
#include <Catalog.h>
|
||||
|
||||
#include "Logger.h"
|
||||
#include "ServerHelper.h"
|
||||
#include "WebAppInterface.h"
|
||||
|
||||
|
||||
#define ATTEMPTS 3
|
||||
#define SPIN_BETWEEN_ATTEMPTS_DELAY_MI 5 * 1000 * 1000
|
||||
// 5 seconds
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "IncrementViewCounterProcess"
|
||||
|
||||
|
||||
IncrementViewCounterProcess::IncrementViewCounterProcess(
|
||||
Model* model, const PackageInfoRef package)
|
||||
:
|
||||
fPackage(package),
|
||||
fModel(model)
|
||||
{
|
||||
fDescription = BString(B_TRANSLATE("Recording view of \"%PackageName%\""))
|
||||
.ReplaceAll("%PackageName%", fPackage->Name());
|
||||
}
|
||||
|
||||
|
||||
IncrementViewCounterProcess::~IncrementViewCounterProcess()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
IncrementViewCounterProcess::Name() const
|
||||
{
|
||||
return "IncrementViewCounterProcess";
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
IncrementViewCounterProcess::Description() const
|
||||
{
|
||||
return fDescription.String();
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
IncrementViewCounterProcess::RunInternal()
|
||||
{
|
||||
if (!ServerHelper::IsNetworkAvailable()) {
|
||||
HDINFO("no network so will not increment view counter");
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
if (!fPackage.IsSet()) {
|
||||
HDERROR("the package is not present to increment the view counter");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
DepotInfoRef depot = fModel->DepotForName(fPackage->DepotName());
|
||||
|
||||
if (!depot.IsSet()) {
|
||||
HDERROR("the package's depot is not present to increment the view "
|
||||
"counter");
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
int32 attempts = ATTEMPTS;
|
||||
status_t result;
|
||||
|
||||
while (attempts > 0 && !WasStopped()) {
|
||||
BMessage resultEnvelope;
|
||||
WebAppInterface& webAppInterface = fModel->GetWebAppInterface();
|
||||
result = webAppInterface.IncrementViewCounter(fPackage, depot,
|
||||
resultEnvelope);
|
||||
|
||||
if (result == B_OK) {
|
||||
int32 errorCode = webAppInterface.ErrorCodeFromResponse(
|
||||
resultEnvelope);
|
||||
switch (errorCode) {
|
||||
case ERROR_CODE_NONE:
|
||||
HDINFO("did increment the view counter for [%s]",
|
||||
fPackage->Name().String());
|
||||
return result;
|
||||
case ERROR_CODE_OBJECTNOTFOUND:
|
||||
HDINFO("server was not able to find the package [%s]",
|
||||
fPackage->Name().String());
|
||||
return B_NAME_NOT_FOUND;
|
||||
default:
|
||||
HDERROR("a problem has arisen incrementing the view "
|
||||
"counter for pkg [%s] w/ error code %" B_PRId32,
|
||||
fPackage->Name().String(), errorCode);
|
||||
result = B_ERROR;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
HDERROR("an error has arisen incrementing the view counter");
|
||||
|
||||
attempts--;
|
||||
_SpinBetweenAttempts();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IncrementViewCounterProcess::_SpinBetweenAttempts()
|
||||
{
|
||||
useconds_t miniSpinDelays = SPIN_BETWEEN_ATTEMPTS_DELAY_MI / 10;
|
||||
for (int32 i = 0; i < 10 && !WasStopped(); i++)
|
||||
usleep(miniSpinDelays);
|
||||
}
|
||||
|
38
src/apps/haikudepot/server/IncrementViewCounterProcess.h
Normal file
38
src/apps/haikudepot/server/IncrementViewCounterProcess.h
Normal file
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2021, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef INCREMENT_VIEW_COUNTER_PROCESS_H
|
||||
#define INCREMENT_VIEW_COUNTER_PROCESS_H
|
||||
|
||||
#include "AbstractProcess.h"
|
||||
#include "Model.h"
|
||||
#include "PackageInfo.h"
|
||||
|
||||
|
||||
class Model;
|
||||
|
||||
|
||||
class IncrementViewCounterProcess : public AbstractProcess {
|
||||
public:
|
||||
IncrementViewCounterProcess(
|
||||
Model* model,
|
||||
const PackageInfoRef package);
|
||||
virtual ~IncrementViewCounterProcess();
|
||||
|
||||
const char* Name() const;
|
||||
const char* Description() const;
|
||||
|
||||
protected:
|
||||
virtual status_t RunInternal();
|
||||
|
||||
private:
|
||||
void _SpinBetweenAttempts();
|
||||
|
||||
private:
|
||||
BString fDescription;
|
||||
PackageInfoRef fPackage;
|
||||
Model* fModel;
|
||||
};
|
||||
|
||||
#endif // INCREMENT_VIEW_COUNTER_PROCESS_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018-2020, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* Copyright 2018-2021, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
|
||||
#include "AbstractServerProcess.h"
|
||||
#include "HaikuDepotConstants.h"
|
||||
#include "IncrementViewCounterProcess.h"
|
||||
#include "LocalPkgDataLoadProcess.h"
|
||||
#include "LocalRepositoryUpdateProcess.h"
|
||||
#include "Logger.h"
|
||||
@ -34,6 +35,21 @@
|
||||
using namespace BPackageKit;
|
||||
|
||||
|
||||
/*static*/ ProcessCoordinator*
|
||||
ProcessCoordinatorFactory::CreateIncrementViewCounter(
|
||||
ProcessCoordinatorListener* processCoordinatorListener,
|
||||
Model* model, const PackageInfoRef package)
|
||||
{
|
||||
ProcessCoordinator* processCoordinator = new ProcessCoordinator(
|
||||
"IncrementViewCounter",
|
||||
processCoordinatorListener);
|
||||
ProcessNode* node = new ProcessNode(
|
||||
new IncrementViewCounterProcess(model, package));
|
||||
processCoordinator->AddNode(node);
|
||||
return processCoordinator;
|
||||
}
|
||||
|
||||
|
||||
/*static*/ ProcessCoordinator*
|
||||
ProcessCoordinatorFactory::CreateUserDetailVerifierCoordinator(
|
||||
UserDetailVerifierListener* userDetailVerifierListener,
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2018, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* Copyright 2018-2021, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -9,6 +9,8 @@
|
||||
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include "PackageInfo.h"
|
||||
|
||||
class Model;
|
||||
class PackageInfoListener;
|
||||
class ProcessCoordinator;
|
||||
@ -21,6 +23,11 @@ class UserDetailVerifierListener;
|
||||
|
||||
class ProcessCoordinatorFactory {
|
||||
public:
|
||||
static ProcessCoordinator* CreateIncrementViewCounter(
|
||||
ProcessCoordinatorListener*
|
||||
processCoordinatorListener,
|
||||
Model* model, const PackageInfoRef package);
|
||||
|
||||
static ProcessCoordinator* CreateBulkLoadCoordinator(
|
||||
PackageInfoListener *packageInfoListener,
|
||||
ProcessCoordinatorListener*
|
||||
@ -38,4 +45,4 @@ private:
|
||||
|
||||
};
|
||||
|
||||
#endif // PROCESS_COORDINATOR_FACTORY_H
|
||||
#endif // PROCESS_COORDINATOR_FACTORY_H
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2014, Stephan Aßmus <superstippi@gmx.de>.
|
||||
* Copyright 2016-2020, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* Copyright 2016-2021, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
@ -758,6 +758,61 @@ WebAppInterface::AuthenticateUser(const BString& nickName,
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
WebAppInterface::IncrementViewCounter(const PackageInfoRef package,
|
||||
const DepotInfoRef depot, BMessage& message)
|
||||
{
|
||||
BMallocIO* requestEnvelopeData = new BMallocIO();
|
||||
// BHttpRequest later takes ownership of this.
|
||||
BJsonTextWriter requestEnvelopeWriter(requestEnvelopeData);
|
||||
|
||||
requestEnvelopeWriter.WriteObjectStart();
|
||||
_WriteStandardJsonRpcEnvelopeValues(requestEnvelopeWriter,
|
||||
"incrementViewCounter");
|
||||
requestEnvelopeWriter.WriteObjectName("params");
|
||||
requestEnvelopeWriter.WriteArrayStart();
|
||||
requestEnvelopeWriter.WriteObjectStart();
|
||||
|
||||
requestEnvelopeWriter.WriteObjectName("architectureCode");
|
||||
requestEnvelopeWriter.WriteString(package->Architecture());
|
||||
requestEnvelopeWriter.WriteObjectName("repositoryCode");
|
||||
requestEnvelopeWriter.WriteString(depot->WebAppRepositoryCode());
|
||||
requestEnvelopeWriter.WriteObjectName("name");
|
||||
requestEnvelopeWriter.WriteString(package->Name());
|
||||
|
||||
const BPackageVersion version = package->Version();
|
||||
if (!version.Major().IsEmpty()) {
|
||||
requestEnvelopeWriter.WriteObjectName("major");
|
||||
requestEnvelopeWriter.WriteString(version.Major());
|
||||
}
|
||||
if (!version.Minor().IsEmpty()) {
|
||||
requestEnvelopeWriter.WriteObjectName("minor");
|
||||
requestEnvelopeWriter.WriteString(version.Minor());
|
||||
}
|
||||
if (!version.Micro().IsEmpty()) {
|
||||
requestEnvelopeWriter.WriteObjectName("micro");
|
||||
requestEnvelopeWriter.WriteString(version.Micro());
|
||||
}
|
||||
if (!version.PreRelease().IsEmpty()) {
|
||||
requestEnvelopeWriter.WriteObjectName("preRelease");
|
||||
requestEnvelopeWriter.WriteString(version.PreRelease());
|
||||
}
|
||||
if (version.Revision() != 0) {
|
||||
requestEnvelopeWriter.WriteObjectName("revision");
|
||||
requestEnvelopeWriter.WriteInteger(
|
||||
static_cast<int64>(version.Revision()));
|
||||
}
|
||||
|
||||
requestEnvelopeWriter.WriteObjectEnd();
|
||||
requestEnvelopeWriter.WriteArrayEnd();
|
||||
requestEnvelopeWriter.WriteObjectEnd();
|
||||
|
||||
return _SendJsonRequest("pkg", requestEnvelopeData,
|
||||
_LengthAndSeekToZero(requestEnvelopeData), 0,
|
||||
message);
|
||||
}
|
||||
|
||||
|
||||
/*! JSON-RPC invocations return a response. The response may be either
|
||||
a result or it may be an error depending on the response structure.
|
||||
If it is an error then there may be additional detail that is the
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright 2014, Stephan Aßmus <superstippi@gmx.de>.
|
||||
* Copyright 2016-2020, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* Copyright 2016-2021, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef WEB_APP_INTERFACE_H
|
||||
@ -12,6 +12,7 @@
|
||||
#include <String.h>
|
||||
#include <package/PackageVersion.h>
|
||||
|
||||
#include "PackageInfo.h"
|
||||
#include "UserCredentials.h"
|
||||
#include "UserDetail.h"
|
||||
#include "UserUsageConditions.h"
|
||||
@ -120,6 +121,11 @@ public:
|
||||
const BString& passwordClear,
|
||||
BMessage& message);
|
||||
|
||||
status_t IncrementViewCounter(
|
||||
const PackageInfoRef package,
|
||||
const DepotInfoRef depot,
|
||||
BMessage& message);
|
||||
|
||||
static int32 ErrorCodeFromResponse(
|
||||
BMessage& responseEnvelopeMessage);
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
#include "RatePackageWindow.h"
|
||||
#include "support.h"
|
||||
#include "ScreenshotWindow.h"
|
||||
#include "SettingsWindow.h"
|
||||
#include "ToLatestUserUsageConditionsWindow.h"
|
||||
#include "UserLoginWindow.h"
|
||||
#include "UserUsageConditionsWindow.h"
|
||||
@ -61,6 +62,7 @@ enum {
|
||||
MSG_REFRESH_REPOS = 'mrrp',
|
||||
MSG_MANAGE_REPOS = 'mmrp',
|
||||
MSG_SOFTWARE_UPDATER = 'mswu',
|
||||
MSG_SETTINGS = 'stgs',
|
||||
MSG_LOG_IN = 'lgin',
|
||||
MSG_AUTHORIZATION_CHANGED = 'athc',
|
||||
MSG_CATEGORIES_LIST_CHANGED = 'clic',
|
||||
@ -76,7 +78,6 @@ enum {
|
||||
};
|
||||
|
||||
#define KEY_ERROR_STATUS "errorStatus"
|
||||
#define KEY_PACKAGE_LIST_VIEW_MODE "packageListViewMode"
|
||||
|
||||
#define TAB_PROMINENT_PACKAGES 0
|
||||
#define TAB_ALL_PACKAGES 1
|
||||
@ -195,6 +196,7 @@ MainWindow::MainWindow(const BMessage& settings)
|
||||
fPackageListView->LoadState(&columnSettings);
|
||||
|
||||
_RestoreModelSettings(settings);
|
||||
_MaybePromptCanShareAnonymousUserData(settings);
|
||||
|
||||
if (fModel.PackageListViewMode() == PROMINENT)
|
||||
fListTabs->Select(TAB_PROMINENT_PACKAGES);
|
||||
@ -343,6 +345,10 @@ MainWindow::MessageReceived(BMessage* message)
|
||||
_OpenLoginWindow(BMessage());
|
||||
break;
|
||||
|
||||
case MSG_SETTINGS:
|
||||
_OpenSettingsWindow();
|
||||
break;
|
||||
|
||||
case MSG_LOG_OUT:
|
||||
fModel.SetNickname("");
|
||||
break;
|
||||
@ -431,8 +437,10 @@ MainWindow::MessageReceived(BMessage* message)
|
||||
}
|
||||
if (!package.IsSet() || name != package->Name())
|
||||
debugger("unable to find the named package");
|
||||
else
|
||||
else {
|
||||
_AdoptPackage(package);
|
||||
_IncrementViewCounter(package);
|
||||
}
|
||||
} else {
|
||||
_ClearPackage();
|
||||
}
|
||||
@ -577,15 +585,19 @@ MainWindow::StoreSettings(BMessage& settings) const
|
||||
|
||||
settings.AddMessage("column settings", &columnSettings);
|
||||
|
||||
settings.AddString(KEY_PACKAGE_LIST_VIEW_MODE,
|
||||
settings.AddString(SETTING_PACKAGE_LIST_VIEW_MODE,
|
||||
main_window_package_list_view_mode_str(
|
||||
fModel.PackageListViewMode()));
|
||||
settings.AddBool("show available packages",
|
||||
settings.AddBool(SETTING_SHOW_AVAILABLE_PACKAGES,
|
||||
fModel.ShowAvailablePackages());
|
||||
settings.AddBool("show installed packages",
|
||||
settings.AddBool(SETTING_SHOW_INSTALLED_PACKAGES,
|
||||
fModel.ShowInstalledPackages());
|
||||
settings.AddBool("show develop packages", fModel.ShowDevelopPackages());
|
||||
settings.AddBool("show source packages", fModel.ShowSourcePackages());
|
||||
settings.AddBool(SETTING_SHOW_DEVELOP_PACKAGES,
|
||||
fModel.ShowDevelopPackages());
|
||||
settings.AddBool(SETTING_SHOW_SOURCE_PACKAGES,
|
||||
fModel.ShowSourcePackages());
|
||||
settings.AddBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA,
|
||||
fModel.CanShareAnonymousUsageData());
|
||||
}
|
||||
|
||||
settings.AddString("username", fModel.Nickname());
|
||||
@ -627,6 +639,14 @@ MainWindow::GetModel()
|
||||
void
|
||||
MainWindow::_BuildMenu(BMenuBar* menuBar)
|
||||
{
|
||||
BMenu* windowMenu = new BMenu(B_TRANSLATE("Window"));
|
||||
windowMenu->AddItem(new BMenuItem(B_TRANSLATE("Settings" B_UTF8_ELLIPSIS),
|
||||
new BMessage(MSG_SETTINGS)));
|
||||
windowMenu->AddSeparatorItem();
|
||||
windowMenu->AddItem(new BMenuItem(B_TRANSLATE("Quit" B_UTF8_ELLIPSIS),
|
||||
new BMessage(B_QUIT_REQUESTED), 'Q'));
|
||||
menuBar->AddItem(windowMenu);
|
||||
|
||||
BMenu* menu = new BMenu(B_TRANSLATE("Tools"));
|
||||
fRefreshRepositoriesItem = new BMenuItem(
|
||||
B_TRANSLATE("Refresh repositories"), new BMessage(MSG_REFRESH_REPOS));
|
||||
@ -635,7 +655,6 @@ MainWindow::_BuildMenu(BMenuBar* menuBar)
|
||||
B_UTF8_ELLIPSIS), new BMessage(MSG_MANAGE_REPOS)));
|
||||
menu->AddItem(new BMenuItem(B_TRANSLATE("Check for updates"
|
||||
B_UTF8_ELLIPSIS), new BMessage(MSG_SOFTWARE_UPDATER)));
|
||||
|
||||
menuBar->AddItem(menu);
|
||||
|
||||
fRepositoryMenu = new BMenu(B_TRANSLATE("Repositories"));
|
||||
@ -756,21 +775,52 @@ void
|
||||
MainWindow::_RestoreModelSettings(const BMessage& settings)
|
||||
{
|
||||
BString packageListViewMode;
|
||||
if (settings.FindString(KEY_PACKAGE_LIST_VIEW_MODE,
|
||||
if (settings.FindString(SETTING_PACKAGE_LIST_VIEW_MODE,
|
||||
&packageListViewMode) == B_OK) {
|
||||
fModel.SetPackageListViewMode(
|
||||
main_window_str_to_package_list_view_mode(packageListViewMode));
|
||||
}
|
||||
|
||||
bool showOption;
|
||||
if (settings.FindBool("show available packages", &showOption) == B_OK)
|
||||
if (settings.FindBool(SETTING_SHOW_AVAILABLE_PACKAGES, &showOption) == B_OK)
|
||||
fModel.SetShowAvailablePackages(showOption);
|
||||
if (settings.FindBool("show installed packages", &showOption) == B_OK)
|
||||
if (settings.FindBool(SETTING_SHOW_INSTALLED_PACKAGES, &showOption) == B_OK)
|
||||
fModel.SetShowInstalledPackages(showOption);
|
||||
if (settings.FindBool("show develop packages", &showOption) == B_OK)
|
||||
if (settings.FindBool(SETTING_SHOW_DEVELOP_PACKAGES, &showOption) == B_OK)
|
||||
fModel.SetShowDevelopPackages(showOption);
|
||||
if (settings.FindBool("show source packages", &showOption) == B_OK)
|
||||
if (settings.FindBool(SETTING_SHOW_SOURCE_PACKAGES, &showOption) == B_OK)
|
||||
fModel.SetShowSourcePackages(showOption);
|
||||
if (settings.FindBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA,
|
||||
&showOption) == B_OK) {
|
||||
fModel.SetCanShareAnonymousUsageData(showOption);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_MaybePromptCanShareAnonymousUserData(const BMessage& settings)
|
||||
{
|
||||
bool showOption;
|
||||
if (settings.FindBool(SETTING_CAN_SHARE_ANONYMOUS_USER_DATA,
|
||||
&showOption) == B_NAME_NOT_FOUND) {
|
||||
_PromptCanShareAnonymousUserData();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_PromptCanShareAnonymousUserData()
|
||||
{
|
||||
BAlert* alert = new(std::nothrow) BAlert(
|
||||
B_TRANSLATE("Sending anonymous usage data"),
|
||||
B_TRANSLATE("Would it be acceptable to send anonymous usage data to the"
|
||||
" HaikuDepotServer system from this computer? You can change your"
|
||||
" preference in the \"Settings\" window later."),
|
||||
B_TRANSLATE("No"),
|
||||
B_TRANSLATE("Yes"));
|
||||
|
||||
int32 result = alert->Go();
|
||||
fModel.SetCanShareAnonymousUsageData(1 == result);
|
||||
}
|
||||
|
||||
|
||||
@ -866,6 +916,31 @@ MainWindow::_AddRemovePackageFromLists(const PackageInfoRef& package)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_IncrementViewCounter(const PackageInfoRef& package)
|
||||
{
|
||||
bool shouldIncrementViewCounter = false;
|
||||
|
||||
{
|
||||
AutoLocker<BLocker> modelLocker(fModel.Lock());
|
||||
bool canShareAnonymousUsageData = fModel.CanShareAnonymousUsageData();
|
||||
if (canShareAnonymousUsageData && !package->Viewed()) {
|
||||
package->SetViewed();
|
||||
shouldIncrementViewCounter = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldIncrementViewCounter) {
|
||||
ProcessCoordinator* bulkLoadCoordinator =
|
||||
ProcessCoordinatorFactory::CreateIncrementViewCounter(
|
||||
this,
|
||||
// ProcessCoordinatorListener
|
||||
&fModel, package);
|
||||
_AddProcessCoordinator(bulkLoadCoordinator);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_AdoptPackage(const PackageInfoRef& package)
|
||||
{
|
||||
@ -1082,6 +1157,14 @@ MainWindow::_PopulatePackageWorker(void* arg)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_OpenSettingsWindow()
|
||||
{
|
||||
SettingsWindow* window = new SettingsWindow(this, &fModel);
|
||||
window->Show();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MainWindow::_OpenLoginWindow(const BMessage& onSuccessMessage)
|
||||
{
|
||||
|
@ -88,6 +88,10 @@ private:
|
||||
void _RestoreWindowFrame(const BMessage& settings);
|
||||
void _RestoreModelSettings(const BMessage& settings);
|
||||
|
||||
void _MaybePromptCanShareAnonymousUserData(
|
||||
const BMessage& settings);
|
||||
void _PromptCanShareAnonymousUserData();
|
||||
|
||||
void _InitWorkerThreads();
|
||||
void _AdoptModelControls();
|
||||
void _AdoptModel();
|
||||
@ -97,6 +101,9 @@ private:
|
||||
void _AdoptPackage(const PackageInfoRef& package);
|
||||
void _ClearPackage();
|
||||
|
||||
void _IncrementViewCounter(
|
||||
const PackageInfoRef& package);
|
||||
|
||||
void _PopulatePackageAsync(bool forcePopulate);
|
||||
void _StartBulkLoad(bool force = false);
|
||||
void _BulkLoadCompleteReceived(status_t errorStatus);
|
||||
@ -118,6 +125,7 @@ private:
|
||||
|
||||
void _OpenLoginWindow(
|
||||
const BMessage& onSuccessMessage);
|
||||
void _OpenSettingsWindow();
|
||||
void _StartUserVerify();
|
||||
void _UpdateAuthorization();
|
||||
void _UpdateAvailableRepositories();
|
||||
|
111
src/apps/haikudepot/ui/SettingsWindow.cpp
Normal file
111
src/apps/haikudepot/ui/SettingsWindow.cpp
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2021, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#include "SettingsWindow.h"
|
||||
|
||||
#include <Button.h>
|
||||
#include <Catalog.h>
|
||||
#include <CheckBox.h>
|
||||
#include <LayoutBuilder.h>
|
||||
#include <Locker.h>
|
||||
#include <SeparatorView.h>
|
||||
|
||||
#include "Logger.h"
|
||||
#include "Model.h"
|
||||
#include "UserUsageConditionsWindow.h"
|
||||
#include "ServerHelper.h"
|
||||
#include "WebAppInterface.h"
|
||||
|
||||
|
||||
#undef B_TRANSLATION_CONTEXT
|
||||
#define B_TRANSLATION_CONTEXT "SettingsWindow"
|
||||
|
||||
#define WINDOW_FRAME BRect(0, 0, 500, 280)
|
||||
|
||||
|
||||
enum {
|
||||
MSG_APPLY = 'aply',
|
||||
};
|
||||
|
||||
|
||||
SettingsWindow::SettingsWindow(BWindow* parent, Model* model)
|
||||
:
|
||||
BWindow(WINDOW_FRAME, B_TRANSLATE("Settings"),
|
||||
B_FLOATING_WINDOW_LOOK, B_MODAL_SUBSET_WINDOW_FEEL,
|
||||
B_ASYNCHRONOUS_CONTROLS | B_AUTO_UPDATE_SIZE_LIMITS
|
||||
| B_NOT_RESIZABLE | B_NOT_ZOOMABLE | B_NOT_CLOSABLE ),
|
||||
fModel(model)
|
||||
{
|
||||
AddToSubset(parent);
|
||||
_InitUiControls();
|
||||
_UpdateUiFromModel();
|
||||
|
||||
BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
|
||||
.AddGroup(B_VERTICAL, 0)
|
||||
.SetInsets(B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING,
|
||||
B_USE_WINDOW_SPACING, B_USE_DEFAULT_SPACING)
|
||||
.Add(fCanShareAnonymousUsageDataCheckBox)
|
||||
.End()
|
||||
.Add(new BSeparatorView(B_HORIZONTAL))
|
||||
// rule off
|
||||
.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
|
||||
.SetInsets(0, B_USE_DEFAULT_SPACING,
|
||||
B_USE_WINDOW_SPACING, B_USE_WINDOW_SPACING)
|
||||
.AddGlue()
|
||||
.Add(fCancelButton)
|
||||
.Add(fApplyButton)
|
||||
.End();
|
||||
|
||||
CenterOnScreen();
|
||||
}
|
||||
|
||||
|
||||
SettingsWindow::~SettingsWindow()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SettingsWindow::_InitUiControls()
|
||||
{
|
||||
fCanShareAnonymousUsageDataCheckBox = new BCheckBox(
|
||||
"share anonymous usage data",
|
||||
B_TRANSLATE("Share anonymous usage data with HaikuDepotServer"), NULL);
|
||||
|
||||
fApplyButton = new BButton("apply", B_TRANSLATE("Apply"),
|
||||
new BMessage(MSG_APPLY));
|
||||
fCancelButton = new BButton("cancel", B_TRANSLATE("Cancel"),
|
||||
new BMessage(B_QUIT_REQUESTED));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SettingsWindow::_UpdateUiFromModel()
|
||||
{
|
||||
fCanShareAnonymousUsageDataCheckBox->SetValue(
|
||||
fModel->CanShareAnonymousUsageData() ? 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SettingsWindow::_UpdateModelFromUi()
|
||||
{
|
||||
fModel->SetCanShareAnonymousUsageData(
|
||||
0 != fCanShareAnonymousUsageDataCheckBox->Value());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SettingsWindow::MessageReceived(BMessage* message)
|
||||
{
|
||||
switch (message->what) {
|
||||
case MSG_APPLY:
|
||||
_UpdateModelFromUi();
|
||||
BMessenger(this).SendMessage(B_QUIT_REQUESTED);
|
||||
break;
|
||||
default:
|
||||
BWindow::MessageReceived(message);
|
||||
break;
|
||||
}
|
||||
}
|
45
src/apps/haikudepot/ui/SettingsWindow.h
Normal file
45
src/apps/haikudepot/ui/SettingsWindow.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2021, Andrew Lindesay <apl@lindesay.co.nz>.
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef SETTINGS_WINDOW_H
|
||||
#define SETTINGS_WINDOW_H
|
||||
|
||||
#include <Locker.h>
|
||||
#include <Messenger.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "BarberPole.h"
|
||||
#include "HaikuDepotConstants.h"
|
||||
#include "UserDetail.h"
|
||||
#include "UserUsageConditions.h"
|
||||
|
||||
|
||||
class BButton;
|
||||
class BCheckBox;
|
||||
class Model;
|
||||
|
||||
|
||||
class SettingsWindow : public BWindow {
|
||||
public:
|
||||
SettingsWindow(BWindow* parent, Model* model);
|
||||
virtual ~SettingsWindow();
|
||||
|
||||
virtual void MessageReceived(BMessage* message);
|
||||
|
||||
private:
|
||||
void _InitUiControls();
|
||||
void _UpdateUiFromModel();
|
||||
void _UpdateModelFromUi();
|
||||
|
||||
private:
|
||||
Model* fModel;
|
||||
|
||||
BCheckBox* fCanShareAnonymousUsageDataCheckBox;
|
||||
|
||||
BButton* fApplyButton;
|
||||
BButton* fCancelButton;
|
||||
};
|
||||
|
||||
|
||||
#endif // SETTINGS_WINDOW_H
|
Loading…
Reference in New Issue
Block a user