Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

부스트 / 페이버릿 단축키 구현 #16

Merged
merged 10 commits into from
Aug 18, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions azalea/assets/icons/retweet-colored.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions azalea/assets/icons/retweet.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions azalea/assets/icons/star-colored.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions azalea/assets/icons/star.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions azalea/azalea.qrc
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
<!DOCTYPE RCC>
<RCC version="1.0">
<!-- https://forum.qt.io/topic/73934/can-t-import-qml-component-using-qrc/7 -->
<qresource prefix="/icons">
<file alias="retweet.svg">assets/icons/retweet-colored.svg</file>
<file alias="star.svg">assets/icons/star-colored.svg</file>
</qresource>
<qresource prefix="/components">
<file alias="Status.qml">ui/timeline/Status.qml</file>
<file alias="Timeline.qml">ui/timeline/Timeline.qml</file>
Expand Down
3 changes: 2 additions & 1 deletion azalea/azaleaapplication.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "azaleaapplication.hpp"

const QString AzaleaApplication::APPLICATION_NAME = "Azalea";
const QString AzaleaApplication::APPLICATION_NAME = "Azalea";
const QString AzaleaApplication::APPLICATION_WEBSITE = "https://azalea.unstabler.pl";

#ifndef AZALEA_VERSION
#ifdef AZALEA_GIT_COMMIT_HASH
Expand Down
1 change: 1 addition & 0 deletions azalea/azaleaapplication.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class AzaleaApplication : public QApplication
public:
static const QString APPLICATION_NAME;
static const QString APPLICATION_VERSION;
static const QString APPLICATION_WEBSITE;

AzaleaApplication(int &argc, char **argv);

Expand Down
2 changes: 2 additions & 0 deletions azalea/mastodon/v1/entities/mastodon.serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ template<> void fromJSON(v1::Status *destination, QJsonObject source)
destination->inReplyToId = source["in_reply_to_id"].toString();
destination->inReplyToAccountId = source["in_reply_to_account_id"].toString();

destination->reblogged = BOOL(source["reblogged"]);
destination->favourited = BOOL(source["favourited"]);

destination->reblog = OBJECT_SHAREDPTR<v1::Status>(source["reblog"]);
destination->content = source["content"].toString();
Expand Down
33 changes: 33 additions & 0 deletions azalea/mastodon/v1/statusesapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,37 @@ namespace v1
QNetworkReply *reply = this->POST(ENDPOINT, argsMap);
return new APIFutureResource<Status>(reply);
}

APIFutureResource<Status> *StatusesAPI::reblog(const QString statusId)
{
const QString endpoint = QString("/api/v1/statuses/%1/reblog").arg(statusId);

auto *reply = this->POST(endpoint, QVariantMap());
return new APIFutureResource<Status>(reply);
}

APIFutureResource<Status> *StatusesAPI::unreblog(const QString statusId)
{
const QString endpoint = QString("/api/v1/statuses/%1/unreblog").arg(statusId);

auto *reply = this->POST(endpoint, QVariantMap());
return new APIFutureResource<Status>(reply);
}

APIFutureResource<Status> *StatusesAPI::favourite(const QString statusId)
{
const QString endpoint = QString("/api/v1/statuses/%1/favourite").arg(statusId);

auto *reply = this->POST(endpoint, QVariantMap());
return new APIFutureResource<Status>(reply);
}

APIFutureResource<Status> *StatusesAPI::unfavourite(const QString statusId)
{
const QString endpoint = QString("/api/v1/statuses/%1/unfavourite").arg(statusId);

auto *reply = this->POST(endpoint, QVariantMap());
return new APIFutureResource<Status>(reply);
}

}
6 changes: 6 additions & 0 deletions azalea/mastodon/v1/statusesapi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ namespace v1
explicit StatusesAPI(APIContext *context);

APIFutureResource<Status> *post(in::PostStatusArgs &args);

APIFutureResource<Status> *reblog(const QString statusId);
APIFutureResource<Status> *unreblog(const QString statusId);
APIFutureResource<Status> *favourite(const QString statusId);
APIFutureResource<Status> *unfavourite(const QString statusId);

};
}

Expand Down
48 changes: 46 additions & 2 deletions azalea/ui/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ void MainWindow::addAccount()
AzaleaApplication::APPLICATION_NAME,
v1::AppsAPI::NO_REDIRECT_URIS,
"read write follow",
"https://azalea.unstabler.pl"
AzaleaApplication::APPLICATION_WEBSITE
);
connect(response, &APIFutureResponse::resolved, [=]() {
auto application = response->tryDeserialize();
Expand Down Expand Up @@ -249,6 +249,11 @@ void MainWindow::notificationsResolved(QSharedPointer<ResourceList<v1::Notificat
}
}

/**
* 스트림 이벤트 핸들러
* @param eventType
* @param payload
*/
void MainWindow::streamEvent(QString eventType, QJsonObject payload)
{
if (eventType == "update") {
Expand Down Expand Up @@ -277,6 +282,16 @@ void MainWindow::keyPressEvent(QKeyEvent *event)
case Qt::Key_Escape:
ui->postArea->blurPostArea();
break;
case Qt::Key_F: {
auto *statusAdapter = getStatusAdapterAtCurrentIndex();
toggleFavourite(statusAdapter);
}
break;
case Qt::Key_T: {
auto *statusAdapter = getStatusAdapterAtCurrentIndex();
toggleBoost(statusAdapter);
}
break;
case Qt::Key_Down:
case Qt::Key_J:
setCurrentIndex(getCurrentIndex() + 1);
Expand All @@ -303,6 +318,8 @@ void MainWindow::keyPressEvent(QKeyEvent *event)

void MainWindow::keyReleaseEvent(QKeyEvent *event)
{
static const int DURATION_MS_FORCE_REFRESH = 500;

if (!event->isAutoRepeat()) {
switch (event->key()) {
case Qt::Key_Space: {
Expand All @@ -311,7 +328,7 @@ void MainWindow::keyReleaseEvent(QKeyEvent *event)
return;
}
// force refresh 여부. 500ms 이상 누르고 있으면 타임라인 내용을 전부 지움
bool clear = QDateTime::currentMSecsSinceEpoch() - _refreshKeyPressedAt > 500;
bool clear = QDateTime::currentMSecsSinceEpoch() - _refreshKeyPressedAt > DURATION_MS_FORCE_REFRESH;
this->updateTimeline(_currentTimeline, clear);
break;
}
Expand Down Expand Up @@ -351,6 +368,33 @@ int MainWindow::getCurrentIndex()
return getQMLTimeline()->property("currentIndex").toInt();
}

StatusAdapterBase *MainWindow::getStatusAdapterAtCurrentIndex()
{
return _timelineModel.at(_currentTimeline)->at(getCurrentIndex());
}

void MainWindow::toggleBoost(StatusAdapterBase *statusAdapter)
{
auto *response = (!statusAdapter->isBoosted()) ?
_api->statuses()->reblog(statusAdapter->id()) :
_api->statuses()->unreblog(statusAdapter->id());

connect(response, &APIFutureResponse::resolved, [statusAdapter] {
statusAdapter->setBoosted(!statusAdapter->isBoosted());
});
}

void MainWindow::toggleFavourite(StatusAdapterBase *statusAdapter)
{
auto *response = (!statusAdapter->isFavourited()) ?
_api->statuses()->favourite(statusAdapter->id()) :
_api->statuses()->unfavourite(statusAdapter->id());

connect(response, &APIFutureResponse::resolved, [statusAdapter] {
statusAdapter->setFavourited(!statusAdapter->isFavourited());
});
}

MainWindow::~MainWindow()
{
delete ui;
Expand Down
4 changes: 4 additions & 0 deletions azalea/ui/mainwindow.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,8 @@ class MainWindow : public QMainWindow
QQuickItem *getQMLTimeline();
void setCurrentIndex(int index);
int getCurrentIndex();
StatusAdapterBase *getStatusAdapterAtCurrentIndex();

void toggleBoost(StatusAdapterBase *statusAdapter);
void toggleFavourite(StatusAdapterBase *statusAdapter);
};
60 changes: 55 additions & 5 deletions azalea/ui/timeline/Status.qml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,52 @@ Rectangle {

property var status: model.display

Rectangle {
// Qt 5.10부터 이런거 사용할 수 있게 되긴 했는데..
// https://doc.qt.io/archives/qt-5.10/qml-qtquick-shapes-shape.html
anchors.left: parent.left
anchors.bottom: parent.bottom

width: parent.width
height: 1

color: "#cacaca"
}

Rectangle {
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: 8

width: 32

Image {
id: boostIcon
fillMode: Image.PreserveAspectFit
width: 16
height: 16
mipmap: true

visible: model.display.boosted

source: "qrc:/icons/retweet.svg" // TODO: boost icon
}
Image {
id: favouriteIcon

anchors.left: boostIcon.right

fillMode: Image.PreserveAspectFit
width: 16
height: 16
mipmap: true

visible: model.display.favourited

source: "qrc:/icons/star.svg" // TODO: boost icon
}
}

Row {
id: row

Expand All @@ -22,6 +68,7 @@ Rectangle {
Rectangle {
width: 48
height: 48
color: "transparent"

Image {
id: profileImage
Expand All @@ -37,13 +84,13 @@ Rectangle {
Image {
id: interactProfileImage

anchors.left: parent.left
anchors.top: parent.top
anchors.margins: 24
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: -4

fillMode: Image.PreserveAspectFit
width: 32
height: 32
width: 24
height: 24
mipmap: true

source: model.display.interactAvatarUrl
Expand Down Expand Up @@ -78,6 +125,9 @@ Rectangle {
renderType: Text.NativeRendering
}




function calculateContentWidth() {
return statusRoot.width - (
parent.spacing + parent.leftPadding + parent.rightPadding + profileImage.width
Expand Down
20 changes: 20 additions & 0 deletions azalea/ui/timeline/notificationstatusadapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,23 @@ QString NotificationStatusAdapter::createdAt()
{
return _notification->createdAt.toTimeZone(QTimeZone::systemTimeZone()).toString(Qt::SystemLocaleLongDate);
}

bool NotificationStatusAdapter::isBoosted()
{
return false;
}

void NotificationStatusAdapter::setBoosted(bool isBoosted)
{

}

bool NotificationStatusAdapter::isFavourited()
{
return false;
}

void NotificationStatusAdapter::setFavourited(bool isFavourited)
{

}
5 changes: 5 additions & 0 deletions azalea/ui/timeline/notificationstatusadapter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ class NotificationStatusAdapter : public StatusAdapterBase
QUrl interactAvatarUrl() override;
QString createdAt() override;

bool isBoosted() override;
void setBoosted(bool isBoosted) override;
bool isFavourited() override;
void setFavourited(bool isFavourited) override;

QSharedPointer<v1::Notification> notification();

private:
Expand Down
23 changes: 22 additions & 1 deletion azalea/ui/timeline/statusadapter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,29 @@ QString StatusAdapter::createdAt()
return _status->createdAt.toTimeZone(QTimeZone::systemTimeZone()).toString(Qt::SystemLocaleLongDate);
}

bool StatusAdapter::isBoosted()
{
return _status->reblogged;
}

void StatusAdapter::setBoosted(bool isBoosted)
{
_status->reblogged = isBoosted;
emit boostToggled(isBoosted);
}

bool StatusAdapter::isFavourited()
{
return _status->favourited;
}

void StatusAdapter::setFavourited(bool isFavourited)
{
_status->favourited = isFavourited;
emit favouriteToggled(isFavourited);
}

QSharedPointer<v1::Status> StatusAdapter::status()
{
return _status;
}

6 changes: 6 additions & 0 deletions azalea/ui/timeline/statusadapter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ class StatusAdapter : public StatusAdapterBase
QUrl interactAvatarUrl() override;
QString createdAt() override;

bool isBoosted() override;
void setBoosted(bool isBoosted) override;
bool isFavourited() override;
void setFavourited(bool isFavourited) override;

QSharedPointer<v1::Status> status();


private:
QSharedPointer<v1::Status> _status;
QList<StatusAdapter*> _replies;
Expand Down
1 change: 0 additions & 1 deletion azalea/ui/timeline/statusadapterbase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,3 @@ QString StatusAdapterBase::formatAuthor(QSharedPointer<v1::Account> account)
account->acct
);
}

Loading