From b31f999348bac22ca9baef7988551245bd1b87c1 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Sat, 28 Sep 2024 17:28:21 +0900 Subject: [PATCH 01/24] =?UTF-8?q?=E3=82=B5=E3=83=A0=E3=83=8D=E7=84=A1?= =?UTF-8?q?=E3=81=97=E3=81=AE=E3=81=A8=E3=81=8D=E3=81=AE=E3=83=AC=E3=82=A4?= =?UTF-8?q?=E3=82=A2=E3=82=A6=E3=83=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/qml/parts/ExternalLinkCard.qml | 2 +- app/qml/parts/VideoFrame.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/qml/parts/ExternalLinkCard.qml b/app/qml/parts/ExternalLinkCard.qml index e8466cad..fb301b27 100644 --- a/app/qml/parts/ExternalLinkCard.qml +++ b/app/qml/parts/ExternalLinkCard.qml @@ -32,7 +32,7 @@ ClickableFrame { ImageWithIndicator { id: thumbImage Layout.preferredWidth: externalLinkFrame.width - Layout.preferredHeight: thumbImage.source !== "" ? externalLinkFrame.width * 0.5 : 5 + Layout.preferredHeight: (thumbImage.source + "") !== "" ? externalLinkFrame.width * 0.5 : 5 fillMode: Image.PreserveAspectCrop } Label { diff --git a/app/qml/parts/VideoFrame.qml b/app/qml/parts/VideoFrame.qml index 9d5a2c00..9229f08b 100644 --- a/app/qml/parts/VideoFrame.qml +++ b/app/qml/parts/VideoFrame.qml @@ -33,7 +33,7 @@ ClickableFrame { id: thumbImage width: videoFrame.width height: { - if(thumbImage.source !== "") { + if((thumbImage.source + "") !== "") { if(sourceSize.width > sourceSize.height){ return (width / sourceSize.width) * sourceSize.height }else{ From 626e0ab223c12d15918eeff42170cffa64f7e9e9 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Sat, 28 Sep 2024 17:53:54 +0900 Subject: [PATCH 02/24] =?UTF-8?q?=E3=83=AA=E3=83=AA=E3=83=BC=E3=82=B9?= =?UTF-8?q?=E3=83=8E=E3=83=BC=E3=83=88=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/content/docs/release-note.en.md | 3 +++ web/content/docs/release-note.ja.md | 3 +++ 2 files changed, 6 insertions(+) diff --git a/web/content/docs/release-note.en.md b/web/content/docs/release-note.en.md index 1d7248d0..c9e9cb4c 100644 --- a/web/content/docs/release-note.en.md +++ b/web/content/docs/release-note.en.md @@ -8,6 +8,9 @@ description: This is a multi-column Bluesky client. ## 2024 +- Fix + - Fix the layout when there is no thumbnail image on the link card + ### v0.38.0 - 2024/9/28 - Update diff --git a/web/content/docs/release-note.ja.md b/web/content/docs/release-note.ja.md index f1448318..99cc052d 100644 --- a/web/content/docs/release-note.ja.md +++ b/web/content/docs/release-note.ja.md @@ -8,6 +8,9 @@ description: マルチカラム対応Blueskyクライアント ## 2024 +- 修正 + - リンクカードにサムネ画像がないときのレイアウトを修正 + ### v0.38.0 - 2024/9/28 - 更新 From 12fcc6b5d01cda45b94605171f612eb807f59ad7 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Wed, 2 Oct 2024 00:37:40 +0900 Subject: [PATCH 03/24] =?UTF-8?q?=E3=83=97=E3=83=AD=E3=83=95=E3=82=A3?= =?UTF-8?q?=E3=83=BC=E3=83=AB=E3=81=AE=E3=83=A9=E3=83=99=E3=83=AB=E3=81=AE?= =?UTF-8?q?=E8=A1=A8=E7=A4=BA=E6=96=B9=E6=B3=95=E3=82=92=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/qml/view/ProfileView.qml | 19 +++++---- app/qtquick/profile/userprofile.cpp | 62 +++++++++-------------------- app/qtquick/profile/userprofile.h | 16 +++----- 3 files changed, 33 insertions(+), 64 deletions(-) diff --git a/app/qml/view/ProfileView.qml b/app/qml/view/ProfileView.qml index 32af03e8..53515914 100644 --- a/app/qml/view/ProfileView.qml +++ b/app/qml/view/ProfileView.qml @@ -362,6 +362,15 @@ ColumnLayout { tagBorderWidth: 1 model: userProfile.belongingLists } + TagLabelLayout { + Layout.preferredWidth: profileView.width - 10 + Layout.maximumWidth: profileView.width + Layout.topMargin: 5 + Layout.leftMargin: 5 + Layout.rightMargin: 5 + visible: count > 0 + model: userProfile.labels + } Label { id: descriptionLabel Layout.topMargin: 5 @@ -508,16 +517,6 @@ ColumnLayout { } ] } - IconLabelFrame { - id: moderationFrame3 - Layout.topMargin: 2 - Layout.preferredWidth: profileView.width - visible: userProfile.userFilterMatched - backgroundColor: Material.color(Material.Red) - borderWidth: 0 - iconSource: "../images/labeling.png" - labelText: qsTr("This account has been flagged : ") + userProfile.userFilterTitle - } IconLabelFrame { id: moderationFrame2 Layout.topMargin: 2 diff --git a/app/qtquick/profile/userprofile.cpp b/app/qtquick/profile/userprofile.cpp index 78d707cf..123ac5fe 100644 --- a/app/qtquick/profile/userprofile.cpp +++ b/app/qtquick/profile/userprofile.cpp @@ -84,29 +84,16 @@ void UserProfile::getProfile(const QString &did) setBlocking(detail.viewer.blocking.contains(m_account.did)); setBlockingUri(detail.viewer.blocking); if (detail.labels.isEmpty()) { - setUserFilterMatched(false); - setUserFilterTitle(QString()); + setLabels(QStringList()); } else { - QString title; - QString val; - for (const auto &label : detail.labels) { + QStringList labels; + for (const auto &label : qAsConst(detail.labels)) { if (label.val == QStringLiteral("!no-unauthenticated")) continue; - val = label.val; - title = labelsTitle(label.val, false); + labels.append(label.val); break; } - if (val.isEmpty()) { - setUserFilterMatched(false); - setUserFilterTitle(QString()); - } else { - setUserFilterMatched(true); - if (title.isEmpty()) { - setUserFilterTitle(val); - } else { - setUserFilterTitle(title); - } - } + setLabels(labels); } setBelongingLists( ListItemsCache::getInstance()->getListNames(m_account.did, detail.did)); @@ -373,32 +360,6 @@ void UserProfile::setBlockingUri(const QString &newBlockingUri) emit blockingUriChanged(); } -bool UserProfile::userFilterMatched() const -{ - return m_userFilterMatched; -} - -void UserProfile::setUserFilterMatched(bool newUserFilterMatched) -{ - if (m_userFilterMatched == newUserFilterMatched) - return; - m_userFilterMatched = newUserFilterMatched; - emit userFilterMatchedChanged(); -} - -QString UserProfile::userFilterTitle() const -{ - return m_userFilterTitle; -} - -void UserProfile::setUserFilterTitle(const QString &newUserFilterTitle) -{ - if (m_userFilterTitle == newUserFilterTitle) - return; - m_userFilterTitle = newUserFilterTitle; - emit userFilterTitleChanged(); -} - QString UserProfile::formattedDescription() const { return m_formattedDescription; @@ -540,6 +501,19 @@ QStringList UserProfile::labelerDids() const return LabelerProvider::getInstance()->labelerDids(m_account); } +QStringList UserProfile::labels() const +{ + return m_labels; +} + +void UserProfile::setLabels(const QStringList &newLabels) +{ + if (m_labels == newLabels) + return; + m_labels = newLabels; + emit labelsChanged(); +} + QStringList UserProfile::belongingLists() const { return m_belongingLists; diff --git a/app/qtquick/profile/userprofile.h b/app/qtquick/profile/userprofile.h index b2af02b8..4091364d 100644 --- a/app/qtquick/profile/userprofile.h +++ b/app/qtquick/profile/userprofile.h @@ -47,11 +47,7 @@ class UserProfile : public QObject Q_PROPERTY(bool blocking READ blocking WRITE setBlocking NOTIFY blockingChanged) Q_PROPERTY(QString blockingUri READ blockingUri WRITE setBlockingUri NOTIFY blockingUriChanged) - Q_PROPERTY(bool userFilterMatched READ userFilterMatched WRITE setUserFilterMatched NOTIFY - userFilterMatchedChanged) - Q_PROPERTY(QString userFilterTitle READ userFilterTitle WRITE setUserFilterTitle NOTIFY - userFilterTitleChanged) - + Q_PROPERTY(QStringList labels READ labels WRITE setLabels NOTIFY labelsChanged FINAL) Q_PROPERTY(QStringList belongingLists READ belongingLists WRITE setBelongingLists NOTIFY belongingListsChanged) Q_PROPERTY(QString pinnedPost READ pinnedPost WRITE setPinnedPost NOTIFY pinnedPostChanged) @@ -107,10 +103,8 @@ class UserProfile : public QObject void setBlocking(bool newBlocking); QString blockingUri() const; void setBlockingUri(const QString &newBlockingUri); - bool userFilterMatched() const; - void setUserFilterMatched(bool newUserFilterMatched); - QString userFilterTitle() const; - void setUserFilterTitle(const QString &newUserFilterTitle); + QStringList labels() const; + void setLabels(const QStringList &newLabels); QStringList belongingLists() const; void setBelongingLists(const QStringList &newBelongingLists); @@ -149,8 +143,9 @@ class UserProfile : public QObject void blockingUriChanged(); void userFilterMatchedChanged(); void userFilterTitleChanged(); - void belongingListsChanged(); + void labelsChanged(); + void belongingListsChanged(); void formattedDescriptionChanged(); void pinnedPostChanged(); void serviceEndpointChanged(); @@ -206,6 +201,7 @@ public slots: QString m_registrationDate; QStringList m_handleHistory; bool m_associatedChatAllow; + QStringList m_labels; }; #endif // USERPROFILE_H From a75433e5fa33dbd4e880534a004b79756ebf52f1 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Wed, 2 Oct 2024 00:38:35 +0900 Subject: [PATCH 04/24] =?UTF-8?q?=E3=83=9D=E3=82=B9=E3=83=88=E3=82=B9?= =?UTF-8?q?=E3=83=AC=E3=83=83=E3=83=89=E3=81=A7=E3=82=A2=E3=82=AB=E3=82=A6?= =?UTF-8?q?=E3=83=B3=E3=83=88=E3=81=AE=E3=83=A9=E3=83=99=E3=83=AB=E3=82=92?= =?UTF-8?q?=E8=A1=A8=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/qml/parts/PostDelegate.qml | 11 +++++++++++ app/qml/parts/TagLabelLayout.qml | 5 +++++ app/qml/view/PostThreadView.qml | 7 +++++-- app/qtquick/atpabstractlistmodel.cpp | 7 +++++-- app/qtquick/atpabstractlistmodel.h | 3 ++- app/qtquick/timeline/timelinelistmodel.cpp | 3 +++ app/qtquick/timeline/timelinelistmodel.h | 1 + 7 files changed, 32 insertions(+), 5 deletions(-) diff --git a/app/qml/parts/PostDelegate.qml b/app/qml/parts/PostDelegate.qml index bbb79032..b9a223f7 100644 --- a/app/qml/parts/PostDelegate.qml +++ b/app/qml/parts/PostDelegate.qml @@ -29,6 +29,7 @@ ClickableFrame { property alias pinnedIndicatorLabel: pinnedIndicatorLabel property alias postAvatarImage: postAvatarImage property alias postAuthor: postAuthor + property alias authorLabels: authorLabels property alias recordText: recordText property alias contentFilterFrame: contentFilterFrame property alias contentMediaFilterFrame: contentMediaFilterFrame @@ -166,6 +167,16 @@ ClickableFrame { Layout.preferredWidth: parent.basisWidth layoutWidth: parent.basisWidth } + TagLabelLayout { + id: authorLabels + Layout.preferredWidth: parent.width + visible: count > 0 + tagSpacing: 2 + tagColor: "transparent" + tagBorderWidth: 1 + fontPointSize: AdjustedValues.f8 + } + CoverFrame { id: contentFilterFrame diff --git a/app/qml/parts/TagLabelLayout.qml b/app/qml/parts/TagLabelLayout.qml index ea712d2e..c7c86472 100644 --- a/app/qml/parts/TagLabelLayout.qml +++ b/app/qml/parts/TagLabelLayout.qml @@ -3,7 +3,10 @@ import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import QtQuick.Controls.Material 2.15 +import tech.relog.hagoromo.singleton 1.0 + Item { + id: tagLabelLayout clip: true implicitHeight: { if(repeater.count === 0){ @@ -23,6 +26,7 @@ Item { property alias model: repeater.model property alias count: repeater.count property string iconSource: "../images/label.png" + property real fontPointSize: AdjustedValues.f10 Repeater { id: repeater @@ -73,6 +77,7 @@ Item { text: model.modelData source: repeater.parent.iconSource spacing: repeater.parent.tagSpacing + fontPointSize: tagLabelLayout.fontPointSize } } } diff --git a/app/qml/view/PostThreadView.qml b/app/qml/view/PostThreadView.qml index 3153db6d..b98b3583 100644 --- a/app/qml/view/PostThreadView.qml +++ b/app/qml/view/PostThreadView.qml @@ -102,6 +102,8 @@ ColumnLayout { delegate: PostDelegate { Layout.preferredWidth: rootListView.width + property bool isBasisPost: (postThreadView.postUri === model.uri) + //自分から自分へは移動しない onClicked: (mouse) => { if(postThreadView.postUri !== model.uri){ @@ -128,7 +130,8 @@ ColumnLayout { postAvatarImage.onClicked: requestViewProfile(model.did) postAuthor.displayName: model.displayName postAuthor.handle: model.handle - postAuthor.indexedAt: (postThreadView.postUri === model.uri) ? "" : model.indexedAt + postAuthor.indexedAt: isBasisPost ? "" : model.indexedAt + authorLabels.model: isBasisPost ? model.authorLabels : [] recordText.text: { var text = model.recordText if(model.recordTextTranslation.length > 0){ @@ -194,7 +197,7 @@ ColumnLayout { listLinkCardFrame.creatorHandleLabel.text: model.listLinkCreatorHandle listLinkCardFrame.descriptionLabel.text: model.listLinkDescription - postInformation.visible: (postThreadView.postUri === model.uri) + postInformation.visible: isBasisPost postInformation.tagsLayout.model: postInformation.visible ? model.tags : [] postInformation.labelsLayout.model: postInformation.visible ? model.labels : [] postInformation.languagesLayout.model: postInformation.visible ? model.languages : [] diff --git a/app/qtquick/atpabstractlistmodel.cpp b/app/qtquick/atpabstractlistmodel.cpp index dd46f95c..7471f862 100644 --- a/app/qtquick/atpabstractlistmodel.cpp +++ b/app/qtquick/atpabstractlistmodel.cpp @@ -400,11 +400,14 @@ bool AtpAbstractListModel::getQuoteFilterMatched( return false; } -QStringList AtpAbstractListModel::getLabels( - const QList &labels) const +QStringList +AtpAbstractListModel::getLabels(const QList &labels, + bool exclude_no_unauth) const { QStringList ret; for (const auto &label : labels) { + if (exclude_no_unauth && label.val == "!no-unauthenticated") + continue; ret.append(label.val); } return ret; diff --git a/app/qtquick/atpabstractlistmodel.h b/app/qtquick/atpabstractlistmodel.h index 2a499ff6..865d496a 100644 --- a/app/qtquick/atpabstractlistmodel.h +++ b/app/qtquick/atpabstractlistmodel.h @@ -202,7 +202,8 @@ public slots: QString getContentFilterMessage(const QList &labels, const bool for_media) const; bool getQuoteFilterMatched(const AtProtocolType::AppBskyFeedDefs::PostView &post) const; - QStringList getLabels(const QList &labels) const; + QStringList getLabels(const QList &labels, + bool exclude_no_unauth = false) const; QStringList getLaunguages(const QVariant &record) const; QString getVia(const QVariant &record) const; diff --git a/app/qtquick/timeline/timelinelistmodel.cpp b/app/qtquick/timeline/timelinelistmodel.cpp index f29d4b13..f4e307b9 100644 --- a/app/qtquick/timeline/timelinelistmodel.cpp +++ b/app/qtquick/timeline/timelinelistmodel.cpp @@ -150,6 +150,8 @@ QVariant TimelineListModel::item(int row, TimelineListModelRoles role) const return current.post.author.handle; else if (role == AvatarRole) return current.post.author.avatar; + else if (role == AuthorLabelsRole) + return getLabels(current.post.author.labels, true); else if (role == MutedRole) return current.post.author.viewer.muted; else if (role == RecordTextRole) @@ -756,6 +758,7 @@ QHash TimelineListModel::roleNames() const roles[DisplayNameRole] = "displayName"; roles[HandleRole] = "handle"; roles[AvatarRole] = "avatar"; + roles[AuthorLabelsRole] = "authorLabels"; roles[MutedRole] = "muted"; roles[RecordTextRole] = "recordText"; roles[RecordTextPlainRole] = "recordTextPlain"; diff --git a/app/qtquick/timeline/timelinelistmodel.h b/app/qtquick/timeline/timelinelistmodel.h index 78186bc6..21fa01f2 100644 --- a/app/qtquick/timeline/timelinelistmodel.h +++ b/app/qtquick/timeline/timelinelistmodel.h @@ -45,6 +45,7 @@ class TimelineListModel : public AtpAbstractListModel DisplayNameRole, HandleRole, AvatarRole, + AuthorLabelsRole, MutedRole, RecordTextRole, RecordTextPlainRole, From 38a63fe441f1a6894034cc4055835dd880523770 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Wed, 2 Oct 2024 00:41:26 +0900 Subject: [PATCH 05/24] =?UTF-8?q?=E3=83=AA=E3=83=AA=E3=83=BC=E3=82=B9?= =?UTF-8?q?=E3=83=8E=E3=83=BC=E3=83=88=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/content/docs/release-note.en.md | 4 ++++ web/content/docs/release-note.ja.md | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/web/content/docs/release-note.en.md b/web/content/docs/release-note.en.md index c9e9cb4c..739b6b1e 100644 --- a/web/content/docs/release-note.en.md +++ b/web/content/docs/release-note.en.md @@ -8,6 +8,10 @@ description: This is a multi-column Bluesky client. ## 2024 +- Add + - Add labels set for the account to the post thread +- Update + - Change the display format of the profile label - Fix - Fix the layout when there is no thumbnail image on the link card diff --git a/web/content/docs/release-note.ja.md b/web/content/docs/release-note.ja.md index 99cc052d..76bc77be 100644 --- a/web/content/docs/release-note.ja.md +++ b/web/content/docs/release-note.ja.md @@ -8,6 +8,10 @@ description: マルチカラム対応Blueskyクライアント ## 2024 +- 追加 + - ポストスレッドにアカウントに設定されたラベルを追加 +- 更新 + - プロフィールのラベルの表示方法を変更 - 修正 - リンクカードにサムネ画像がないときのレイアウトを修正 From fda34e49b1024903be14565cd94de93ac18622b8 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Wed, 2 Oct 2024 21:48:06 +0900 Subject: [PATCH 06/24] =?UTF-8?q?=E6=80=AA=E3=81=97=E3=81=84=E3=83=A9?= =?UTF-8?q?=E3=83=99=E3=83=AB=E3=82=92=E9=99=A4=E5=A4=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/qtquick/atpabstractlistmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/qtquick/atpabstractlistmodel.cpp b/app/qtquick/atpabstractlistmodel.cpp index 7471f862..ae57a2fe 100644 --- a/app/qtquick/atpabstractlistmodel.cpp +++ b/app/qtquick/atpabstractlistmodel.cpp @@ -406,7 +406,7 @@ AtpAbstractListModel::getLabels(const QList Date: Wed, 2 Oct 2024 22:47:02 +0900 Subject: [PATCH 07/24] =?UTF-8?q?Revert=20"=E6=80=AA=E3=81=97=E3=81=84?= =?UTF-8?q?=E3=83=A9=E3=83=99=E3=83=AB=E3=82=92=E9=99=A4=E5=A4=96"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit fda34e49b1024903be14565cd94de93ac18622b8. --- app/qtquick/atpabstractlistmodel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/qtquick/atpabstractlistmodel.cpp b/app/qtquick/atpabstractlistmodel.cpp index ae57a2fe..7471f862 100644 --- a/app/qtquick/atpabstractlistmodel.cpp +++ b/app/qtquick/atpabstractlistmodel.cpp @@ -406,7 +406,7 @@ AtpAbstractListModel::getLabels(const QList Date: Tue, 8 Oct 2024 02:04:18 +0900 Subject: [PATCH 08/24] =?UTF-8?q?jetstream=E5=AF=BE=E5=BF=9C=E3=81=AE?= =?UTF-8?q?=E5=8F=97=E4=BF=A1=E5=87=A6=E7=90=86=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sync/comatprotosyncsubscribereposex.cpp | 81 ++++++++++++++++++- .../sync/comatprotosyncsubscribereposex.h | 11 ++- 2 files changed, 89 insertions(+), 3 deletions(-) diff --git a/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.cpp b/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.cpp index b628ca2f..e919dff9 100644 --- a/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.cpp +++ b/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.cpp @@ -15,7 +15,8 @@ namespace AtProtocolInterface { -ComAtprotoSyncSubscribeReposEx::ComAtprotoSyncSubscribeReposEx(QObject *parent) : QObject { parent } +ComAtprotoSyncSubscribeReposEx::ComAtprotoSyncSubscribeReposEx(QObject *parent) + : QObject { parent }, m_subscribeMode { SubScribeMode::Firehose } { qDebug().noquote() << "ComAtprotoSyncSubscribeReposEx"; @@ -56,9 +57,10 @@ ComAtprotoSyncSubscribeReposEx::ComAtprotoSyncSubscribeReposEx(QObject *parent) }); } -void ComAtprotoSyncSubscribeReposEx::open(const QUrl &url) +void ComAtprotoSyncSubscribeReposEx::open(const QUrl &url, SubScribeMode mode) { if (m_webSocket.state() == QAbstractSocket::UnconnectedState) { + m_subscribeMode = mode; m_webSocket.open(url); } } @@ -88,6 +90,15 @@ void ComAtprotoSyncSubscribeReposEx::onDisconnected() void ComAtprotoSyncSubscribeReposEx::onBinaryMessageReceived(const QByteArray &message) { // qDebug().noquote() << "onBinaryMessageReceived" << message.length(); + if (m_subscribeMode == SubScribeMode::JetStream) { + messageReceivedFromJetStream(message); + } else { + messageReceivedFromFirehose(message); + } +} + +void ComAtprotoSyncSubscribeReposEx::messageReceivedFromFirehose(const QByteArray &message) +{ CarDecoder decoder(true); int offset = 0; @@ -135,4 +146,70 @@ void ComAtprotoSyncSubscribeReposEx::onBinaryMessageReceived(const QByteArray &m m_webSocket.close(); } } + +void ComAtprotoSyncSubscribeReposEx::messageReceivedFromJetStream(const QByteArray &message) +{ + + QString payload_type; + + QJsonDocument doc = QJsonDocument::fromJson(message); + QJsonObject json_src = doc.object(); + QHash commit_type_to; + commit_type_to["c"] = "create"; + commit_type_to["u"] = "update"; + commit_type_to["d"] = "delete"; + + if (doc.isNull()) { + qDebug().noquote() << "Invalid data"; + qDebug().noquote() << "message:" << message; + emit errorOccured("InvalidData", "Unreadable JSON data."); + m_webSocket.close(); + } else if (!json_src.contains("type") || !json_src.contains("did") + || !json_src.contains("commit")) { + qDebug().noquote() << "Invalid data"; + qDebug().noquote() << "message:" << message; + emit errorOccured("InvalidData", "Unanticipated data structure."); + m_webSocket.close(); + } else { + payload_type = "#commit"; + + QJsonObject json_src_commit = json_src.value("commit").toObject(); + QJsonObject json_dest; + qDebug().noquote() << "message:" << message; + json_dest.insert("repo", json_src.value("did").toString()); + json_dest.insert("rev", json_src_commit.value("rev").toString()); + json_dest.insert("time", + QDateTime::fromMSecsSinceEpoch(json_src.value("time_us").toInt() / 1000) + .toString(Qt::ISODateWithMs)); + + QJsonObject json_dest_commit; + json_dest_commit.insert("$link", json_src_commit.value("cid").toString()); + json_dest.insert("commit", json_dest_commit); + + QJsonObject json_dest_op; + json_dest_op.insert("action", + commit_type_to.value(json_src_commit.value("type").toString())); + json_dest_op.insert("path", + QString("%1/%2").arg(json_src_commit.value("collection").toString(), + json_src_commit.value("rkey").toString())); + json_dest_op.insert("cid", json_dest_commit); + QJsonArray json_dest_ops; + json_dest_ops.append(json_dest_op); + json_dest.insert("ops", json_dest_ops); + + QJsonObject json_dest_block; + QJsonArray json_dest_blocks; + json_dest_block.insert("cid", json_src_commit.value("cid").toString()); + json_dest_block.insert("uri", + QString("at://%1/%2/%3") + .arg(json_src.value("did").toString(), + json_src_commit.value("collection").toString(), + json_src_commit.value("rkey").toString())); + json_dest_block.insert("value", json_src_commit.value("record").toObject()); + json_dest_blocks.append(json_dest_block); + json_dest.insert("blocks", json_dest_blocks); + + emit received(payload_type, json_dest); + } +} } diff --git a/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.h b/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.h index 20b3109b..aefd926c 100644 --- a/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.h +++ b/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.h @@ -12,9 +12,14 @@ class ComAtprotoSyncSubscribeReposEx : public QObject { Q_OBJECT public: + enum SubScribeMode : int { + Firehose, + JetStream, + }; + explicit ComAtprotoSyncSubscribeReposEx(QObject *parent = nullptr); - void open(const QUrl &url); + void open(const QUrl &url, SubScribeMode mode = SubScribeMode::Firehose); void close(); QAbstractSocket::SocketState state() const; @@ -30,8 +35,12 @@ public slots: void onBinaryMessageReceived(const QByteArray &message); private: + void messageReceivedFromFirehose(const QByteArray &message); + void messageReceivedFromJetStream(const QByteArray &message); + QWebSocket m_webSocket; QStringList m_payloadTypeList; + SubScribeMode m_subscribeMode; }; } From 88ad36d45649563737dd84afb13cece0aebccbeb Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Tue, 8 Oct 2024 21:34:32 +0900 Subject: [PATCH 09/24] =?UTF-8?q?firehose=E3=81=A8jetstream=E3=82=92?= =?UTF-8?q?=E9=81=B8=E6=8A=9E=E3=81=A7=E3=81=8D=E3=82=8B=E3=82=88=E3=81=86?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sync/comatprotosyncsubscribereposex.cpp | 27 ++++++++++++------- .../sync/comatprotosyncsubscribereposex.h | 1 + tools/firehosereader/main.cpp | 17 +++++++++++- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.cpp b/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.cpp index e919dff9..cdd4328f 100644 --- a/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.cpp +++ b/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.cpp @@ -32,6 +32,8 @@ ComAtprotoSyncSubscribeReposEx::ComAtprotoSyncSubscribeReposEx(QObject *parent) &ComAtprotoSyncSubscribeReposEx::onConnected); connect(&m_webSocket, &QWebSocket::binaryMessageReceived, this, &ComAtprotoSyncSubscribeReposEx::onBinaryMessageReceived); + connect(&m_webSocket, &QWebSocket::textMessageReceived, this, + &ComAtprotoSyncSubscribeReposEx::onTextMessageReceived); connect(&m_webSocket, &QWebSocket::disconnected, this, &ComAtprotoSyncSubscribeReposEx::onDisconnected); @@ -90,13 +92,18 @@ void ComAtprotoSyncSubscribeReposEx::onDisconnected() void ComAtprotoSyncSubscribeReposEx::onBinaryMessageReceived(const QByteArray &message) { // qDebug().noquote() << "onBinaryMessageReceived" << message.length(); - if (m_subscribeMode == SubScribeMode::JetStream) { - messageReceivedFromJetStream(message); - } else { + if (m_subscribeMode == SubScribeMode::Firehose) { messageReceivedFromFirehose(message); } } +void ComAtprotoSyncSubscribeReposEx::onTextMessageReceived(const QString &message) +{ + if (m_subscribeMode == SubScribeMode::JetStream) { + messageReceivedFromJetStream(message.toUtf8()); + } +} + void ComAtprotoSyncSubscribeReposEx::messageReceivedFromFirehose(const QByteArray &message) { @@ -159,27 +166,27 @@ void ComAtprotoSyncSubscribeReposEx::messageReceivedFromJetStream(const QByteArr commit_type_to["u"] = "update"; commit_type_to["d"] = "delete"; - if (doc.isNull()) { + if (doc.isNull() || json_src.isEmpty()) { qDebug().noquote() << "Invalid data"; qDebug().noquote() << "message:" << message; emit errorOccured("InvalidData", "Unreadable JSON data."); m_webSocket.close(); } else if (!json_src.contains("type") || !json_src.contains("did") || !json_src.contains("commit")) { - qDebug().noquote() << "Invalid data"; - qDebug().noquote() << "message:" << message; - emit errorOccured("InvalidData", "Unanticipated data structure."); - m_webSocket.close(); + qDebug().noquote() << "Unsupport data:" << message; + // emit errorOccured("InvalidData", "Unanticipated data structure."); + // m_webSocket.close(); } else { payload_type = "#commit"; QJsonObject json_src_commit = json_src.value("commit").toObject(); QJsonObject json_dest; - qDebug().noquote() << "message:" << message; + json_dest.insert("repo", json_src.value("did").toString()); json_dest.insert("rev", json_src_commit.value("rev").toString()); json_dest.insert("time", - QDateTime::fromMSecsSinceEpoch(json_src.value("time_us").toInt() / 1000) + QDateTime::fromMSecsSinceEpoch( + static_cast(json_src.value("time_us").toDouble() / 1000)) .toString(Qt::ISODateWithMs)); QJsonObject json_dest_commit; diff --git a/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.h b/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.h index aefd926c..22c1c33f 100644 --- a/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.h +++ b/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.h @@ -33,6 +33,7 @@ public slots: void onConnected(); void onDisconnected(); void onBinaryMessageReceived(const QByteArray &message); + void onTextMessageReceived(const QString &message); private: void messageReceivedFromFirehose(const QByteArray &message); diff --git a/tools/firehosereader/main.cpp b/tools/firehosereader/main.cpp index 3a5f6e7d..f6ca7b5f 100644 --- a/tools/firehosereader/main.cpp +++ b/tools/firehosereader/main.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "comatprotosyncsubscribereposex.h" @@ -18,11 +19,22 @@ int main(int argc, char *argv[]) qWarning() << " usage: firehosereader URL STOPER_USER_DID"; return 1; } + ComAtprotoSyncSubscribeReposEx::SubScribeMode mode = + ComAtprotoSyncSubscribeReposEx::SubScribeMode::Firehose; QUrl url(a.arguments().at(1)); QString stopper_did = a.arguments().at(2); qDebug().noquote() << "url" << url.toString(); + qDebug().noquote() << " " << url.scheme(); + qDebug().noquote() << " " << url.host(); + qDebug().noquote() << " " << url.path(); + qDebug().noquote() << " " << url.query(); qDebug().noquote() << "Stopper" << stopper_did; // wss://bsky.network/xrpc/com.atproto.sync.subscribeRepos + // wss://jetstream2.us-west.bsky.network/subscribe?wantedCollections=app.bsky.feed.post&wantedCollections=app.bsky.feed.repost&wantedCollections=app.bsky.graph.follow + + if (url.host().startsWith("jetstream")) { + mode = ComAtprotoSyncSubscribeReposEx::SubScribeMode::JetStream; + } QElapsedTimer timer; timer.start(); @@ -105,7 +117,10 @@ int main(int argc, char *argv[]) QCoreApplication::quit(); } }); - client.open(url); + client.open(url, mode); + + QNetworkRequest req(url); + qDebug().noquote() << req.url().toString() << req.url().query(); return a.exec(); } From f6e54dd1c987d287932c27600b3719faf994cf30 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Tue, 8 Oct 2024 23:03:28 +0900 Subject: [PATCH 10/24] =?UTF-8?q?=E3=83=87=E3=83=BC=E3=82=BF=E3=81=AE?= =?UTF-8?q?=E7=B5=84=E3=81=BF=E7=AB=8B=E3=81=A6=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../sync/comatprotosyncsubscribereposex.cpp | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.cpp b/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.cpp index cdd4328f..86ce548e 100644 --- a/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.cpp +++ b/lib/extension/com/atproto/sync/comatprotosyncsubscribereposex.cpp @@ -194,26 +194,32 @@ void ComAtprotoSyncSubscribeReposEx::messageReceivedFromJetStream(const QByteArr json_dest.insert("commit", json_dest_commit); QJsonObject json_dest_op; - json_dest_op.insert("action", - commit_type_to.value(json_src_commit.value("type").toString())); + QString commit_type = commit_type_to.value(json_src_commit.value("type").toString()); + json_dest_op.insert("action", commit_type); json_dest_op.insert("path", QString("%1/%2").arg(json_src_commit.value("collection").toString(), json_src_commit.value("rkey").toString())); - json_dest_op.insert("cid", json_dest_commit); + if (commit_type == "delete") { + json_dest_op.insert("cid", QJsonValue()); + } else { + json_dest_op.insert("cid", json_dest_commit); + } QJsonArray json_dest_ops; json_dest_ops.append(json_dest_op); json_dest.insert("ops", json_dest_ops); - QJsonObject json_dest_block; QJsonArray json_dest_blocks; - json_dest_block.insert("cid", json_src_commit.value("cid").toString()); - json_dest_block.insert("uri", - QString("at://%1/%2/%3") - .arg(json_src.value("did").toString(), - json_src_commit.value("collection").toString(), - json_src_commit.value("rkey").toString())); - json_dest_block.insert("value", json_src_commit.value("record").toObject()); - json_dest_blocks.append(json_dest_block); + if (json_src_commit.contains("record")) { + QJsonObject json_dest_block; + json_dest_block.insert("cid", json_src_commit.value("cid").toString()); + json_dest_block.insert("uri", + QString("at://%1/%2/%3") + .arg(json_src.value("did").toString(), + json_src_commit.value("collection").toString(), + json_src_commit.value("rkey").toString())); + json_dest_block.insert("value", json_src_commit.value("record").toObject()); + json_dest_blocks.append(json_dest_block); + } json_dest.insert("blocks", json_dest_blocks); emit received(payload_type, json_dest); From 5a64fed48dae51612d937b587a554c9b1e7d837d Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Wed, 9 Oct 2024 01:38:37 +0900 Subject: [PATCH 11/24] =?UTF-8?q?GUI=E3=81=A7jetstream=E3=82=92=E4=BD=BF?= =?UTF-8?q?=E3=81=86=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/realtime/firehosereceiver.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/realtime/firehosereceiver.cpp b/lib/realtime/firehosereceiver.cpp index 158791f7..c474b238 100644 --- a/lib/realtime/firehosereceiver.cpp +++ b/lib/realtime/firehosereceiver.cpp @@ -5,6 +5,8 @@ // #include #include +#define USE_JETSTREAM + using AtProtocolInterface::ComAtprotoSyncSubscribeReposEx; namespace RealtimeFeed { @@ -18,7 +20,11 @@ FirehoseReceiver::FirehoseReceiver(QObject *parent) , m_status(FirehoseReceiverStatus::Disconnected) { +#ifdef USE_JETSTREAM + m_serviceEndpoint = "wss://jetstream2.us-west.bsky.network"; +#else m_serviceEndpoint = "wss://bsky.network"; +#endif m_wdgTimer.setInterval(60 * 1000); connect(&m_client, &ComAtprotoSyncSubscribeReposEx::errorOccured, @@ -97,9 +103,19 @@ void FirehoseReceiver::start() if (path.endsWith("/")) { path.resize(path.length() - 1); } +#ifdef USE_JETSTREAM + ComAtprotoSyncSubscribeReposEx::SubScribeMode mode = + ComAtprotoSyncSubscribeReposEx::SubScribeMode::JetStream; + QUrl url(path + + "/subscribe?wantedCollections=app.bsky.feed.post&wantedCollections=app.bsky.feed." + "repost&wantedCollections=app.bsky.graph.follow"); +#else + ComAtprotoSyncSubscribeReposEx::SubScribeMode mode = + ComAtprotoSyncSubscribeReposEx::SubScribeMode::Firehose; QUrl url(path + "/xrpc/com.atproto.sync.subscribeRepos"); +#endif qDebug().noquote() << "Connect to" << url.toString(); - m_client.open(url); + m_client.open(url, mode); m_wdgTimer.start(); } From 67dc1d5ac8c84ad5e8faa594470b5be71e4a8759 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Wed, 9 Oct 2024 20:52:08 +0900 Subject: [PATCH 12/24] =?UTF-8?q?=E3=83=AA=E3=83=AA=E3=83=BC=E3=82=B9?= =?UTF-8?q?=E3=83=8E=E3=83=BC=E3=83=88=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/content/docs/release-note.en.md | 1 + web/content/docs/release-note.ja.md | 1 + 2 files changed, 2 insertions(+) diff --git a/web/content/docs/release-note.en.md b/web/content/docs/release-note.en.md index 739b6b1e..77170086 100644 --- a/web/content/docs/release-note.en.md +++ b/web/content/docs/release-note.en.md @@ -12,6 +12,7 @@ description: This is a multi-column Bluesky client. - Add labels set for the account to the post thread - Update - Change the display format of the profile label + - Reduces the amount of data transmitted in real-time feeds - Fix - Fix the layout when there is no thumbnail image on the link card diff --git a/web/content/docs/release-note.ja.md b/web/content/docs/release-note.ja.md index 76bc77be..40acc80f 100644 --- a/web/content/docs/release-note.ja.md +++ b/web/content/docs/release-note.ja.md @@ -12,6 +12,7 @@ description: マルチカラム対応Blueskyクライアント - ポストスレッドにアカウントに設定されたラベルを追加 - 更新 - プロフィールのラベルの表示方法を変更 + - リアルタイムフィードの通信量を軽減 - 修正 - リンクカードにサムネ画像がないときのレイアウトを修正 From acccdfafb423ddda683dff751b1fcdccd82df062 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Thu, 10 Oct 2024 23:26:41 +0900 Subject: [PATCH 13/24] =?UTF-8?q?OGP=E3=81=AE=E5=8F=96=E5=BE=97=E5=87=A6?= =?UTF-8?q?=E7=90=86=E3=81=AE=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/tools/opengraphprotocol.cpp | 16 +++++++++++++- tests/atprotocol_test/atprotocol_test.qrc | 1 + tests/atprotocol_test/response/ogp/file7.html | 19 ++++++++++++++++ tests/atprotocol_test/tst_atprotocol_test.cpp | 22 +++++++++++++++++++ 4 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 tests/atprotocol_test/response/ogp/file7.html diff --git a/lib/tools/opengraphprotocol.cpp b/lib/tools/opengraphprotocol.cpp index e96e5aa5..ca97f36d 100644 --- a/lib/tools/opengraphprotocol.cpp +++ b/lib/tools/opengraphprotocol.cpp @@ -28,6 +28,16 @@ void OpenGraphProtocol::getData(const QString &url) m_thumb.clear(); QNetworkRequest request((QUrl(url))); + request.setRawHeader(QByteArray("accept"), QByteArray("*/*")); + request.setRawHeader(QByteArray("sec-ch-ua-platform"), QByteArray("Windows")); + request.setRawHeader(QByteArray("sec-fetch-dest"), QByteArray("document")); + request.setRawHeader(QByteArray("sec-fetch-mode"), QByteArray("navigate")); + request.setRawHeader(QByteArray("sec-fetch-site"), QByteArray("none")); + request.setRawHeader(QByteArray("sec-fetch-user"), QByteArray("?1")); + request.setHeader(QNetworkRequest::UserAgentHeader, + "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, " + "like Gecko) Chrome/129.0.0.0 Safari/537.36"); + request.setTransferTimeout(60 * 1000); QNetworkAccessManager *manager = new QNetworkAccessManager(this); connect(manager, &QNetworkAccessManager::finished, [=](QNetworkReply *reply) { @@ -54,6 +64,9 @@ void OpenGraphProtocol::getData(const QString &url) emit reply->redirectAllowed(); } }); + connect(reply, &QNetworkReply::errorOccurred, [=](QNetworkReply::NetworkError code) { + qDebug() << "Reply error:" << code << reply->request().url(); + }); } void OpenGraphProtocol::downloadThumb(const QString &path) @@ -172,7 +185,8 @@ bool OpenGraphProtocol::parse(const QByteArray &data, const QString &src_uri) QDomDocument doc; rebuildHtml(ts.readAll(), doc); #else - QTextCodec *codec = QTextCodec::codecForHtml(data, QTextCodec::codecForName("utf-8")); + QString charset = extractCharset(QString::fromUtf8(data)); + QTextCodec *codec = QTextCodec::codecForHtml(data, QTextCodec::codecForName(charset.toUtf8())); QDomDocument doc; rebuildHtml(codec->toUnicode(data), doc); #endif diff --git a/tests/atprotocol_test/atprotocol_test.qrc b/tests/atprotocol_test/atprotocol_test.qrc index c6e8272a..ea69cbb8 100644 --- a/tests/atprotocol_test/atprotocol_test.qrc +++ b/tests/atprotocol_test/atprotocol_test.qrc @@ -74,5 +74,6 @@ response/labels/provider/2/xrpc/app.bsky.labeler.getServices data/postgate/1/xrpc/com.atproto.repo.createRecord data/postgate/2/xrpc/com.atproto.repo.createRecord + response/ogp/file7.html diff --git a/tests/atprotocol_test/response/ogp/file7.html b/tests/atprotocol_test/response/ogp/file7.html new file mode 100644 index 00000000..80363aa1 --- /dev/null +++ b/tests/atprotocol_test/response/ogp/file7.html @@ -0,0 +1,19 @@ + + + + + + + + +^Cg^O + + + + + + + + +file7 + diff --git a/tests/atprotocol_test/tst_atprotocol_test.cpp b/tests/atprotocol_test/tst_atprotocol_test.cpp index 154e400f..ea60273d 100644 --- a/tests/atprotocol_test/tst_atprotocol_test.cpp +++ b/tests/atprotocol_test/tst_atprotocol_test.cpp @@ -441,6 +441,28 @@ void atprotocol_test::test_OpenGraphProtocol() .arg(QString::number(m_listenPort)), ogp.thumb().toLocal8Bit()); } + + { + QSignalSpy spy(&ogp, SIGNAL(finished(bool))); + ogp.getData(m_service + "/ogp/file7.html"); + spy.wait(); + QVERIFY2(spy.count() == 1, QString("spy.count()=%1").arg(spy.count()).toUtf8()); + + QList arguments = spy.takeFirst(); + QVERIFY(arguments.at(0).toBool()); + + QVERIFY2(ogp.uri() + == QString("http://localhost:%1/response/ogp/file7.html") + .arg(QString::number(m_listenPort)), + ogp.uri().toLocal8Bit()); + QVERIFY2(ogp.title() == QString("file7 TITLE"), ogp.title().toLocal8Bit()); + QVERIFY2(ogp.description() == QString("file7 ").append(QChar(0x8a73)).append(QChar(0x7d30)), + ogp.description().toLocal8Bit()); + QVERIFY2(ogp.thumb() + == QString("http://localhost:%1/response/ogp/images/file7.png") + .arg(QString::number(m_listenPort)), + ogp.thumb().toLocal8Bit()); + } } void atprotocol_test::test_ogpDecodeHtml() From c5df0b88adcad8bacf103bb247b7cedc00b8fb79 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Thu, 10 Oct 2024 23:28:02 +0900 Subject: [PATCH 14/24] =?UTF-8?q?=E3=83=AA=E3=83=AA=E3=83=BC=E3=82=B9?= =?UTF-8?q?=E3=83=8E=E3=83=BC=E3=83=88=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/content/docs/release-note.en.md | 1 + web/content/docs/release-note.ja.md | 1 + 2 files changed, 2 insertions(+) diff --git a/web/content/docs/release-note.en.md b/web/content/docs/release-note.en.md index 77170086..adb6a4cd 100644 --- a/web/content/docs/release-note.en.md +++ b/web/content/docs/release-note.en.md @@ -15,6 +15,7 @@ description: This is a multi-column Bluesky client. - Reduces the amount of data transmitted in real-time feeds - Fix - Fix the layout when there is no thumbnail image on the link card + - Fix a case where the information on the link card could not be obtained ### v0.38.0 - 2024/9/28 diff --git a/web/content/docs/release-note.ja.md b/web/content/docs/release-note.ja.md index 40acc80f..369b34df 100644 --- a/web/content/docs/release-note.ja.md +++ b/web/content/docs/release-note.ja.md @@ -15,6 +15,7 @@ description: マルチカラム対応Blueskyクライアント - リアルタイムフィードの通信量を軽減 - 修正 - リンクカードにサムネ画像がないときのレイアウトを修正 + - リンクカードの情報を取得できないケースを修正 ### v0.38.0 - 2024/9/28 From 81a4b42b577fb32dc008cfdeeb5fb1129ab0e8cc Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Fri, 11 Oct 2024 01:19:37 +0900 Subject: [PATCH 15/24] =?UTF-8?q?lib=E7=94=A8=E7=BF=BB=E8=A8=B3=E3=83=87?= =?UTF-8?q?=E3=83=BC=E3=82=BF=E3=81=AE=E4=BD=9C=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/app.pro | 3 +- app/i18n/app_ja.qm | Bin 42149 -> 42219 bytes app/i18n/app_ja.ts | 389 ++++++++------------------------ app/tools/translatorchanger.cpp | 15 +- app/tools/translatorchanger.h | 1 + lib/i18n/lib_ja.qm | Bin 0 -> 3878 bytes lib/i18n/lib_ja.ts | 286 +++++++++++++++++++++++ lib/lib.pro | 2 + 8 files changed, 395 insertions(+), 301 deletions(-) create mode 100644 lib/i18n/lib_ja.qm create mode 100644 lib/i18n/lib_ja.ts diff --git a/app/app.pro b/app/app.pro index 13b96c5a..41319d55 100644 --- a/app/app.pro +++ b/app/app.pro @@ -203,7 +203,8 @@ win32:{ translations.path = $$install_dir/translations mac:translations.path = \ $$install_dir/$${TARGET}.app/Contents/MacOS/translations -translations.files = $$PWD/i18n/*.qm +translations.files = $$PWD/i18n/*.qm \ + $$PWD/../lib/i18n/*.qm #qmファイルが存在しないとmakefileに追加されないので注意 INSTALLS += translations diff --git a/app/i18n/app_ja.qm b/app/i18n/app_ja.qm index 76495fb44b72466d0cbf26324a87a547444295d8..55732027ab158fb39c9809cd2aa43268f924e7d6 100644 GIT binary patch delta 1986 zcmX|?dsGzH9ml^j`@TdlR+7LO7kES(gPphQH_^61zoH?g|?0jbL+gmsc^3zyX&;?ZfL@A0GE}0q> z_V6`GPa6fQ%8>45f^()L{SW~wXUnX5mj)G%DOF#he0-_v0IGg>8VKm|>n1nQY)0!} z4+D)^WL28izl^hCR-j}6{i#0!TOZo~hG{Q3c4XDjEr6V49&oXfwbWb;a7R*Z5x zvVQ_L4$CZ4aCM3Q0iqMQcQ^Wh!WL>#PSg3@xyNI(f!#;xlG4IgKcHJm^E@SAFtivj zYxp9^7~nq77u{!?iw^NS_GGXOzR2%f#>S`K=9>o{z`PkU>z|TSWt|z!AA4v4@|1jE zXCE+kA3rqk0LXsE4_#$aSqJ&+Ut9ztm&>gAma0|Jy50X)ME{nFxMJv%$}*|(nPOdn z2pA74*6(F!$>bDikG}<4R?&zmjL+#MjXEx}tWELh2eSb0n4+hX&7LrzxYGPLU`xGX zc*1rd%%z0#OBTTt@~Xr5x|`IXwsTq3!LGCDYjx|Y{AbGjN$1%PU&!>0$*k;_xp||^ z+F<4WKd{&%&B}Lf@XT)Wl)mYF`H{>Wz2wxI zxyh8Mb#ewO*T$LZkErYkaV)|dRfL-Pu;C@@)jB3^8B(Rv7T{+JnGGGP*E-KJ!82qK z%n=Jz1(#XCGpDOOnK6LhqAHV^PQoLZJEK**mh`aMcPT}1@a}t5E!c%{)!S7}$@P#r z1T$Amy+Vw!LUrjDGw{;2s>|cga)-#EvvO{7>a4;F^~CiZfG0rfbaqZl)$BT%+H~>U zUiw~VjX0n_x{&2UaaDcn!Zx<{q`LhDmWzzFGP5#d?wLW(Aji_Cx70WM?=bmp^@B%q zfLEf_qwoKj6*V-LJGX$MzsRhZq?z&Y-+@i@WtO=#vBhIR@)FIW@0iu|u2EZ1%*=F6 zmpY2Quq`ruXEi;VVb&oEHD8@!HrwzknI$@z6$i+mH%~NZet7>Tkodah{{B~yX4M>3mhwYjdZfSQlBxs}X?w%gjgq&Hbf56P_G zq%DjJWk>dF3s*L>dD+^+^ec?JwAC*hXJxfqTN9eWvfM1Qd6-7@PHsL~gVz~@v|kS_ z1&TE?%k9(&uCDz@GZ}2M6`0HWH5yBO+92c z#Bhm}X|OUwRvV`AP4}qHkjqt&A;iihku$_Dd<4Al znarX$sUgI|S3Rb-ka%IUJ|$HE@-Nazh&>`h-bmNQL~3NgwrAdzXx8@iBZQ@K{^&(qmS|PK>L3Wd6%C1vlOTsUKxRc`B+mA83>16s|7C$`2jFbI2 z<(ll_P2z2n$fEU&PyWHaQPWQtxHC`Kmnq($uK5#-?-X^I%-m+`HQ6~MjhM_4enZz= z`M~1UhEMzISbuiOEDadWE2jd6RWgga$r)6COr`cdkWa;3Xcr}Q4XPtNRVtY!b#OZ@-0j$G~C;I?ID pXM0OMz7kupdsAtCvD;SZEw%Z)wjyt?E#G6y%4ISRn)}{{{{fV}a>@Vz delta 1984 zcmXAqdsGv57RT>QW|B-uW(X)*j@u;KmTW=DP$?;_1*#rd(JfjZ9EFu)!uw@KL`4en zFp!{uy*(C1OAl17?N(4)d>pM?s|%!B+U*u)eW1Hl%b{z#eMo6N(rf3Bna`QuncwgC zz4!OM_cuPs9vEa>%)(LtcpjjJZM9jL&8^9~!U^Es@&eTUrS-T?=m73c1Hda|t#@~@ zO$k`a*n~sCAFKk{G6y@DC^mNu4l$-J0%JjLYS;{eJ= z6mD6^)H{C!csWtwrhKL$`Tqd1Nz5DT>i`OWL?0KXs~4G{9>xId(&Aap%+{>IQO*=s zz!nTI05ECTqNs-eIkVWJ?`Y5Y``G$jYbozdY~x}YfAS{l9f|^oi&W^&LOXAXE@Qjy zn*s6)*nyq_fM;K2hy6cLoKAN55^a^$&R+S)2LR!JR=E97Sk1@kcD<;IJxZIn_TyRJ z9PV+d(vm~~W4mf~3u(z@R2j4P0<5c26(9ZrKx$K!Xc7Q&BT-T(%&Rb{PW){SzzB?pT06wT(8w!(6k!mZ&7D~A-tqEakpTU03+VCBr z+?DfWDEoT~8zQ-@{a*nDCvn&C6#)61!iHK*)!LbItkxz3xi$Q6Dvde(Q);rP+k->e zs5Mn{`Bk_LV7f|S<8(f~=OjS&@A#J{$!Lkud|pR4KvE-Lu>DOs<3oJGhm@4)2)-oK zLC&w|H_4F+=dtwTFx4e>*BMGdo`jYF6NBgoh|+mMeZB5=+CCgh146=!pVydgk5Zl0Xd>VL zlI+~2aFbs%cf&(~B?~q4?@$@!$6|MYW6?QHuli|#(*Gzde@t^hGeX^?Q1itxvS9H? z3d`0j+&rbZYN5mgc{O*q=>TD8G~<5yKffI9dJ|KF$@+z?+m1fHNw}-cb&>D3&%kcI zDf+Uu@abTZGo~$E)r*u7=#+p#Xv=hY zOQ|XshA8w#pj~n>?_#cGA@{kZFxI;QyQN&_2ATpbOgB0LEpeRzgI1cfs83;YNWkFZ z_vm{(;O5&@MeO?l<3HR6aQXwjouuz|rxX_bg1$gATe%jy0~3W?`qWjVuHXrr2(&Th z(PA_iC-og8Tc}L4^qu!#AS?V6lZ`f^LElqA$B=yzD~$HIONM26CjnxfH8^9bbGbe> z)WuSXFaEcoqp1X7d7t5^<2B0pO2heqxs;Wah6g4Z_g%+PW2nP%iS7@lOH4);2{nu9 zjz!ebykb%OVSwkZiDmsONK?C5^#M;tSgNq*RkR10XYDkKzN9}=Vh@Y^YrDu->lJQ1 zBEI|1Mw0ReEDf^7eJkD!B0>3M;^bF!QAHe-m}8S?Hx=5q?pDCznroX202QsVCc z=)acIi|11ty@f+Tw$&9<&mkMY@6SoS)ikCG{c_X22n?D%1E1*n1)JZ@{1qg$b-e%p diff --git a/app/i18n/app_ja.ts b/app/i18n/app_ja.ts index b7618585..96a5f649 100644 --- a/app/i18n/app_ja.ts +++ b/app/i18n/app_ja.ts @@ -9,7 +9,7 @@ アカウント管理 - + Set as main メインに設定 @@ -18,7 +18,7 @@ ポストの統計とログ - + Content filter コンテンツフィルター @@ -27,17 +27,17 @@ ミュート中 - + Muted words and tags ミュートワードの編集 - + Muted accounts ミュート中のアカウント - + Muted lists ミュート中のリスト @@ -46,32 +46,32 @@ ブロック中 - + Statistics and logs 統計とログ - + Mute ミュート - + Block ブロック - + Blocked accounts ブロック中のアカウント - + Blocked lists ブロック中のリスト - + Post interaction settings 投稿への反応の設定 @@ -80,12 +80,12 @@ リプライできるユーザー - + Remove account アカウントを削除 - + Close 閉じる @@ -273,14 +273,14 @@ AtpAbstractListModel - - + + Blocked ブロック中 - - + + Detached by author 投稿者によって切り離し済み @@ -685,137 +685,6 @@ Please recreate AppPassword in the official application. 設定 - - ConfigurableLabels - - Content hidden - 閲覧不可 - - - Moderator overrides for special cases. - 特別な場合のためのモデレーターによるオーバーライド。 - - - Content warning - 閲覧警告 - - - Legal - 法的 - - - Content removed for legal reasons. - 法的な理由で削除されたコンテンツ。 - - - Explicit Sexual Images - 露骨な性的な画像 - - - i.e. pornography - 例えばポルノ - - - Sexually Explicit - 露骨な性的表現 - - - Other Nudity - その他ヌード - - - Including non-sexual and artistic - ノンセクシャルや芸術的なものも含む - - - Nudity - ヌード - - - Basic Moderation - 基本モデレーション - - - Basic configuration independent of moderation services. - モデレーションサービスに依存しない基本設定。 - - - Pornography - ポルノ - - - Explicit sexual images. - 露骨な性的な画像。 - - - Sexually Suggestive - 性的な示唆 - - - Does not include nudity - ヌードは含まない - - - Graphic Media - グラフィックメディア - - - Explicit or potentially disturbing media. - 露骨な、あるいは不穏なメディア。 - - - Non-sexual Nudity - 性的でないヌード - - - E.g. artistic nudes. - 例:芸術的なヌード - - - Violent / Bloody - 暴力 / 流血 - - - Gore, self-harm, torture - 血糊、自傷行為、拷問 - - - Violence - 暴力 - - - Hate Group Iconography - ヘイトグループの象徴 - - - Images of terror groups, articles covering events, etc. - テロ集団の画像、事件を取り上げた記事など - - - Hate Groups - ヘイトグループ - - - Spam - スパム - - - Excessive unwanted interactions - 過剰な不要な干渉 - - - Impersonation / Scam - なりすまし / 詐欺 - - - Impersonation - なりすまし - - - Accounts falsely claiming to be people or orgs - 個人や団体を偽ったアカウント - - ContentFilterSettingDialog @@ -2082,93 +1951,6 @@ Please recreate AppPassword in the official application. ブロック中 - - LogAccess - - Post - ポスト - - - Total number of posts - 総ポスト数 - - - Number of days posts - ポストした日数 - - - Average number of daily posts - 1日あたりの平均ポスト数 - - - Like - いいね - - - Total number of likes - 総いいね数 - - - Number of days likes - いいねした日数 - - - Average number of daily likes - 1日あたりの平均いいね数 - - - Repost - リポスト - - - Total number of reposts - 総リポスト数 - - - Number of days reposts - リポストした日数 - - - Average number of daily reposts - 1日あたりの平均リポスト数 - - - List - リスト - - - Total number of lists - リストの数 - - - Total number of list items - リストに登録している総アカウント数 - - - Other - その他 - - - Total number of follows - フォロー数 - - - Total number of who can reply - リプライ制限をした数 - - - Total number of blocks - 総ブロック数 - - - Number of registrations for list - リストに登録しているアカウント数 - - - Number of registrations for '%1' - '%1'に登録しているアカウント数 - - LogViewDialog @@ -2306,7 +2088,7 @@ Please recreate AppPassword in the official application. NotificationListModel - + Post hidden by muted word ミュートワードを含む @@ -2322,83 +2104,83 @@ Please recreate AppPassword in the official application. PostControls - + Repost リポスト - + Quote 引用 - - + + Translate 翻訳 - - + + Copy post text ポストをコピー - - + + Copy url URLをコピー - - + + Open in Official 公式で開く - - + + Reposted by リポストしたアカウント - - + + Liked by いいねしたアカウント - - + + Quotes 引用したポスト - - + + Unpin this post 固定ポストを解除 - - + + Pin this post 固定ポストにする - - + + Unmute thread スレッドミュートの解除 - - + + Mute thread スレッドをミュート - + Edit interaction settings 投稿への反応の設定 @@ -2407,22 +2189,22 @@ Please recreate AppPassword in the official application. リプライできるユーザー - + Delete post ポストを削除 - + Re-attach quote 引用を再接続 - + Detach quote 引用を切断 - + Report post ポストを通報 @@ -2430,7 +2212,7 @@ Please recreate AppPassword in the official application. PostDelegate - + Post from an account you muted. ミュートしているアカウントのポスト @@ -2506,7 +2288,7 @@ Please recreate AppPassword in the official application. ポストスレッド - + Quoted content warning 閲覧注意な引用 @@ -2592,87 +2374,86 @@ Please recreate AppPassword in the official application. 登録日 : - + Send mention メンションを送る - + Send message メッセージを送る - + Copy handle ハンドルをコピー - + Copy DID DIDをコピー - + Copy Official Url 公式のURLをコピー - + Open in new col 新しいカラムで開く - + Open in Official 公式で開く - + Add/Remove from lists リストへ追加/削除 - + Unmute account ミュート解除 - + Mute account ミュート - + Unblock account ブロック解除 - + Block account ブロック - + Report account 通報 - + Account blocked ブロックしたアカウント - + Account muted ミュートしたアカウント - This account has been flagged : - このアカウントに設定されたラベル : + このアカウントに設定されたラベル : - + This account has blocked you あなたをブロックしているアカウント @@ -2810,28 +2591,28 @@ Please recreate AppPassword in the official application. - + Update list ... (%1) - + Update who can reply ... - - + + Update quote status ... - + Uploading images ... (%1/%2) - + Delete list item ... (%1) @@ -3606,7 +3387,7 @@ Why should this message be reviewed? TimelineListModel - + Post hidden by muted word ミュートワードを含む @@ -3614,7 +3395,7 @@ Why should this message be reviewed? TimelineView - + Quoted content warning 閲覧注意な引用 @@ -3627,7 +3408,7 @@ Why should this message be reviewed? - + Search posts 検索(ポスト) @@ -3641,23 +3422,33 @@ Why should this message be reviewed? リプライできるユーザーの更新中 ... - - + + Authentication error + 認証エラー + + + + Some accounts require you to log in again. + いくつかのアカウントでログインが必要です。 + + + + Updating 'Edit interaction settings' ... 投稿への反応の設定を更新中 ... - + Loading lists リストの読み込み中 - + Chat チャット - + Loading account(s) ... アカウント情報の読み込み中 ... diff --git a/app/tools/translatorchanger.cpp b/app/tools/translatorchanger.cpp index 10d687ea..80ab5777 100644 --- a/app/tools/translatorchanger.cpp +++ b/app/tools/translatorchanger.cpp @@ -27,13 +27,20 @@ void TranslatorChanger::initialize(QCoreApplication *app, QQmlApplicationEngine t->deleteLater(); } t = new QTranslator(this); + if (t->load(QString("lib_%1").arg(lang), dir)) { + m_translatorLib[lang] = t; + } else { + t->deleteLater(); + } + t = new QTranslator(this); if (t->load(QString("qt_%1").arg(lang), dir)) { m_translatorSys[lang] = t; } else { t->deleteLater(); } } - qDebug() << "Loaded languages" << m_translatorApp.keys(); + qDebug() << "Loaded languages" << m_translatorApp.keys() << m_translatorLib.keys() + << m_translatorSys.keys(); } void TranslatorChanger::connect() @@ -81,6 +88,9 @@ void TranslatorChanger::change(const QString &lang) if (m_translatorApp.contains(m_currentLang)) { m_app->removeTranslator(m_translatorApp[m_currentLang]); } + if (m_translatorLib.contains(m_currentLang)) { + m_app->removeTranslator(m_translatorLib[m_currentLang]); + } if (m_translatorSys.contains(m_currentLang)) { m_app->removeTranslator(m_translatorSys[m_currentLang]); } @@ -90,6 +100,9 @@ void TranslatorChanger::change(const QString &lang) if (m_translatorApp.contains(lang)) { m_app->installTranslator(m_translatorApp[lang]); } + if (m_translatorLib.contains(lang)) { + m_app->installTranslator(m_translatorLib[lang]); + } if (m_translatorSys.contains(lang)) { m_app->installTranslator(m_translatorSys[lang]); } diff --git a/app/tools/translatorchanger.h b/app/tools/translatorchanger.h index 982bf7cc..8a8be886 100644 --- a/app/tools/translatorchanger.h +++ b/app/tools/translatorchanger.h @@ -25,6 +25,7 @@ public slots: QCoreApplication *m_app; QQmlApplicationEngine *m_engine; QHash m_translatorApp; + QHash m_translatorLib; QHash m_translatorSys; QString m_currentLang; }; diff --git a/lib/i18n/lib_ja.qm b/lib/i18n/lib_ja.qm new file mode 100644 index 0000000000000000000000000000000000000000..830df881ecb6d06c18679b534aa5407be57d5050 GIT binary patch literal 3878 zcma)94Qvx-82-xETi5-H115r=MDTBn7c>&Y7{DzP7+qZl(-(}nK>s`IOj!k~T z1kKp+4+2Ki7{q{R{E28(A|Z(6$UXRqV`(>ln+qmYscU zA7i=gp7PHv?0d%Zgbe(`9iELj_PX4&(PskpRL=LZhDaXGIsfBW1au&G%dhx8caL{< z((gUq=Sl*=?egwCw-x@c7K)=!W8YIk&Ae@h??xf?7yS6932#jRo`0_J1$82iTl4Zy zuf^ww^D4SdVqKQ^?yhyPe=hHz6^JKqu5WxpBXH07Uiou8;ys?fZP)FHr`3PxIM%`o z{y%i&F|4ED__s3=Pi5isACR9nuW+q|RhU!w!kS9Ny}fWBI}g7Fg=gMefp`uSiBk|? zPH$1qCnj(v6o2~UHQ0ZkWZWU(GFGB)!RG~Ulq?sgF;+BP!AlP^W@CZ{f$g+%!O6N1 ztqCqAnVRTTdXqNOdD`ovFOXz5}z7vo%yt6bC# z{6)Rx{60cxaHsFqo$Mo@5-MxMb?u6~x&aX_({0S<(l%NHR2Z z(=E_a`Vtl1M|#6;w9KxqgEFd0=ccIX778h=i7*$nL|Cyp-Oz^D_5L^d@sGMgcJe7? z2d}KUGFmB0hNYMm=m4-G8c_OdpgvBmfudDi)cS~_sqToYimZS=h8WlF&MT4% zm4uN&!f3X2660Y-a;4Gml)r^H*(FI#4<1bOFv{^@@{R=ht;D405LGGbp0Q*lICYG))l$>@4$jE?B#VnRhMtIvv!PTyYU8@nshBPUbf60Q zpqFg?|C~Ifp54ayE4EJ4?XlC@pm2k{FVum|Kr>?ZM=jdu#16vZ>j#U|;Df;msbrm0b8C^3-PVkZ z1UhXyOW$W&S@spD@No5M;=iQjTNX$wU8gx{<%&~D4QW4EKBb5=S(X6^BQqixye48Q zS88itymkt3BFL$?|3aFUmDrDI@F>pN)QvGUG*rCLQXzpJCM|H(sie2gYT-uKjmbou zjk!TkBg;NtU&_u-p+4E~EPD%=9;Bmm);>AY(iqvGTbOSB>~2Ucm!2j^-T%#YazS^b^sgR~~e`n187S%yU|Iu0=nH}$xh9Exc& F{~rj}M=k&W literal 0 HcmV?d00001 diff --git a/lib/i18n/lib_ja.ts b/lib/i18n/lib_ja.ts new file mode 100644 index 00000000..b4c5dc46 --- /dev/null +++ b/lib/i18n/lib_ja.ts @@ -0,0 +1,286 @@ + + + + + ConfigurableLabels + + + + Content hidden + 閲覧不可 + + + + + Moderator overrides for special cases. + 特別な場合のためのモデレーターによるオーバーライド。 + + + + + Content warning + 閲覧警告 + + + + + Legal + 法的 + + + + Content removed for legal reasons. + 法的な理由で削除されたコンテンツ。 + + + Explicit Sexual Images + 露骨な性的な画像 + + + i.e. pornography + 例えばポルノ + + + + Sexually Explicit + 露骨な性的表現 + + + Other Nudity + その他ヌード + + + Including non-sexual and artistic + ノンセクシャルや芸術的なものも含む + + + Nudity + ヌード + + + + Basic Moderation + 基本モデレーション + + + + Basic configuration independent of moderation services. + モデレーションサービスに依存しない基本設定。 + + + + Pornography + ポルノ + + + + Explicit sexual images. + 露骨な性的な画像。 + + + + + Sexually Suggestive + 性的な示唆 + + + + Does not include nudity + ヌードは含まない + + + + + Graphic Media + グラフィックメディア + + + + Explicit or potentially disturbing media. + 露骨な、あるいは不穏なメディア。 + + + + + Non-sexual Nudity + 性的でないヌード + + + + E.g. artistic nudes. + 例:芸術的なヌード + + + + Violent / Bloody + 暴力 / 流血 + + + + Gore, self-harm, torture + 血糊、自傷行為、拷問 + + + + Violence + 暴力 + + + + Hate Group Iconography + ヘイトグループの象徴 + + + + Images of terror groups, articles covering events, etc. + テロ集団の画像、事件を取り上げた記事など + + + + Hate Groups + ヘイトグループ + + + + + Spam + スパム + + + + Excessive unwanted interactions + 過剰な不要な干渉 + + + + Impersonation / Scam + なりすまし / 詐欺 + + + + Impersonation + なりすまし + + + + Accounts falsely claiming to be people or orgs + 個人や団体を偽ったアカウント + + + + LogAccess + + + + + Post + ポスト + + + + Total number of posts + 総ポスト数 + + + + Number of days posts + ポストした日数 + + + + Average number of daily posts + 1日あたりの平均ポスト数 + + + + + + Like + いいね + + + + Total number of likes + 総いいね数 + + + + Number of days likes + いいねした日数 + + + + Average number of daily likes + 1日あたりの平均いいね数 + + + + + + Repost + リポスト + + + + Total number of reposts + 総リポスト数 + + + + Number of days reposts + リポストした日数 + + + + Average number of daily reposts + 1日あたりの平均リポスト数 + + + + + List + リスト + + + + Total number of lists + リストの数 + + + + Total number of list items + リストに登録している総アカウント数 + + + + + + Other + その他 + + + + Total number of follows + フォロー数 + + + + Total number of who can reply + リプライ制限をした数 + + + + Total number of blocks + 総ブロック数 + + + + Number of registrations for list + リストに登録しているアカウント数 + + + Number of registrations for '%1' + '%1'に登録しているアカウント数 + + + diff --git a/lib/lib.pro b/lib/lib.pro index 9480d9d8..5b6763c6 100644 --- a/lib/lib.pro +++ b/lib/lib.pro @@ -13,6 +13,8 @@ unix:INCLUDEPATH += ../openssl/include DEFINES += CPPHTTPLIB_ZLIB_SUPPORT # zlib support for cpp-httplib +TRANSLATIONS += i18n/lib_ja.ts + SOURCES += \ $$PWD/atprotocol/accessatprotocol.cpp \ $$PWD/atprotocol/app/bsky/actor/appbskyactorgetpreferences.cpp \ From 6043db50e0761541b9c2044edc8159e66dc13ef7 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Fri, 11 Oct 2024 01:30:15 +0900 Subject: [PATCH 16/24] =?UTF-8?q?linux,Mac=E3=81=AE=E3=82=B9=E3=82=AF?= =?UTF-8?q?=E3=83=AA=E3=83=97=E3=83=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/build.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/build.sh b/scripts/build.sh index e1d7e155..9dee6c70 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -85,6 +85,7 @@ deploy_hagoromo(){ cp "zlib/lib/libz.so.1.3.1" ${work_dir}/lib cp "zlib/lib/libz.so.1" ${work_dir}/lib cp "app/i18n/app_ja.qm" ${work_dir}/bin/translations + cp "app/i18n/lib_ja.qm" ${work_dir}/bin/translations cp ${QT_BIN_FOLDER}/../translations/qt_ja.qm ${work_dir}/bin/translations cat ${SCRIPT_FOLDER}/deploy/linux_lib.txt | xargs -i{} cp -P ${QT_BIN_FOLDER}/../lib/{} ${work_dir}/lib @@ -99,6 +100,7 @@ deploy_hagoromo(){ mkdir -p ${work_dir}/Hagoromo.app/Contents/MacOS/translations cp "app/i18n/app_ja.qm" ${work_dir}/Hagoromo.app/Contents/MacOS/translations + cp "app/i18n/lib_ja.qm" ${work_dir}/Hagoromo.app/Contents/MacOS/translations cp ${QT_BIN_FOLDER}/../translations/qt_ja.qm ${work_dir}/Hagoromo.app/Contents/MacOS/translations cp -RL "zlib/lib/libz.1.dylib" ${work_dir}/Hagoromo.app/Contents/Frameworks fi From e95aebda90f39b161494437533125d4fe890e902 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Fri, 11 Oct 2024 01:50:42 +0900 Subject: [PATCH 17/24] =?UTF-8?q?=E3=83=93=E3=83=AB=E3=83=89=E3=82=B9?= =?UTF-8?q?=E3=82=AF=E3=83=AA=E3=83=97=E3=83=88=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/build.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/build.sh b/scripts/build.sh index 9dee6c70..6b5d7c12 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -85,7 +85,7 @@ deploy_hagoromo(){ cp "zlib/lib/libz.so.1.3.1" ${work_dir}/lib cp "zlib/lib/libz.so.1" ${work_dir}/lib cp "app/i18n/app_ja.qm" ${work_dir}/bin/translations - cp "app/i18n/lib_ja.qm" ${work_dir}/bin/translations + cp "lib/i18n/lib_ja.qm" ${work_dir}/bin/translations cp ${QT_BIN_FOLDER}/../translations/qt_ja.qm ${work_dir}/bin/translations cat ${SCRIPT_FOLDER}/deploy/linux_lib.txt | xargs -i{} cp -P ${QT_BIN_FOLDER}/../lib/{} ${work_dir}/lib @@ -100,7 +100,7 @@ deploy_hagoromo(){ mkdir -p ${work_dir}/Hagoromo.app/Contents/MacOS/translations cp "app/i18n/app_ja.qm" ${work_dir}/Hagoromo.app/Contents/MacOS/translations - cp "app/i18n/lib_ja.qm" ${work_dir}/Hagoromo.app/Contents/MacOS/translations + cp "lib/i18n/lib_ja.qm" ${work_dir}/Hagoromo.app/Contents/MacOS/translations cp ${QT_BIN_FOLDER}/../translations/qt_ja.qm ${work_dir}/Hagoromo.app/Contents/MacOS/translations cp -RL "zlib/lib/libz.1.dylib" ${work_dir}/Hagoromo.app/Contents/Frameworks fi @@ -134,8 +134,8 @@ fi VERSION_NO=$(cat app/main.cpp | grep "app.setApplicationVersion" | grep -oE "[0-9]+.[0-9]+.[0-9]+") -build_openssl -build_zlib +# build_openssl +# build_zlib build_hagoromo deploy_hagoromo # update_web From 2ed384761a7df2ed800f6c1c96aa7b166d6baec4 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Fri, 11 Oct 2024 19:18:10 +0900 Subject: [PATCH 18/24] =?UTF-8?q?=E3=83=93=E3=83=AB=E3=83=89=E3=82=B9?= =?UTF-8?q?=E3=82=AF=E3=83=AA=E3=83=97=E3=83=88=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- scripts/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/build.sh b/scripts/build.sh index 6b5d7c12..11787ce9 100755 --- a/scripts/build.sh +++ b/scripts/build.sh @@ -134,8 +134,8 @@ fi VERSION_NO=$(cat app/main.cpp | grep "app.setApplicationVersion" | grep -oE "[0-9]+.[0-9]+.[0-9]+") -# build_openssl -# build_zlib +build_openssl +build_zlib build_hagoromo deploy_hagoromo # update_web From b521851ceb48d48e97ed4b3522ef5d780255c299 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Fri, 11 Oct 2024 19:18:17 +0900 Subject: [PATCH 19/24] Update git ignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index d1b22020..9e7cd6ed 100644 --- a/.gitignore +++ b/.gitignore @@ -65,6 +65,7 @@ openssl/bin openssl/certs openssl/include openssl/lib +openssl/lib64 openssl/misc openssl/private openssl/share From 117fabf2e7805f452316168ddde25a580cdcc570 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Fri, 11 Oct 2024 21:30:21 +0900 Subject: [PATCH 20/24] =?UTF-8?q?=E3=83=8F=E3=83=83=E3=82=B7=E3=83=A5?= =?UTF-8?q?=E3=82=BF=E3=82=B0=E3=82=92=E3=82=B3=E3=83=94=E3=83=BC=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=83=A1=E3=83=8B=E3=83=A5=E3=83=BC=E3=82=92=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/qml/parts/HashTagMenu.qml | 7 +++++++ app/qml/parts/NotificationDelegate.qml | 2 ++ app/qml/parts/PostDelegate.qml | 2 ++ app/qml/view/NotificationListView.qml | 1 + app/qml/view/PostThreadView.qml | 1 + app/qml/view/TimelineView.qml | 1 + 6 files changed, 14 insertions(+) diff --git a/app/qml/parts/HashTagMenu.qml b/app/qml/parts/HashTagMenu.qml index 276ab98a..0c09d27e 100644 --- a/app/qml/parts/HashTagMenu.qml +++ b/app/qml/parts/HashTagMenu.qml @@ -11,6 +11,7 @@ MenuEx { signal requestViewSearchPosts(string text) signal requestAddMutedWord(string text) + signal requestCopyTagToClipboard(string text) Action { enabled: !logMode @@ -25,6 +26,12 @@ MenuEx { text: qsTr("Search %s posts by this user").replace("%s", tagMenu.tagText) onTriggered: requestViewSearchPosts(tagMenu.tagText + " from:" + postAuthor.handle) } + Action { + enabled: !logMode + icon.source: "../images/copy.png" + text: qsTr("Copy %s").replace("%s", tagMenu.tagText) + onTriggered: requestCopyTagToClipboard(tagMenu.tagText) + } MenuSeparator {} Action { icon.source: "../images/mute.png" diff --git a/app/qml/parts/NotificationDelegate.qml b/app/qml/parts/NotificationDelegate.qml index 5cd3bded..5cc79676 100644 --- a/app/qml/parts/NotificationDelegate.qml +++ b/app/qml/parts/NotificationDelegate.qml @@ -56,6 +56,7 @@ ClickableFrame { signal requestViewProfile(string did) signal requestViewSearchPosts(string text) signal requestAddMutedWord(string text) + signal requestCopyTagToClipboard(string text) function openLink(url){ if(url.indexOf("did:") === 0){ @@ -282,6 +283,7 @@ ClickableFrame { id: tagMenu onRequestViewSearchPosts: (text) => notificationFrame.requestViewSearchPosts(text) onRequestAddMutedWord: (text) => notificationFrame.requestAddMutedWord(text) + onRequestCopyTagToClipboard: (text) => notificationFrame.requestCopyTagToClipboard(text) } } } diff --git a/app/qml/parts/PostDelegate.qml b/app/qml/parts/PostDelegate.qml index b9a223f7..d1943b76 100644 --- a/app/qml/parts/PostDelegate.qml +++ b/app/qml/parts/PostDelegate.qml @@ -54,6 +54,7 @@ ClickableFrame { signal requestViewProfile(string did) signal requestViewSearchPosts(string text) signal requestAddMutedWord(string text) + signal requestCopyTagToClipboard(string text) function openLink(url){ if(url.indexOf("did:") === 0){ @@ -217,6 +218,7 @@ ClickableFrame { logMode: postFrame.logMode onRequestViewSearchPosts: (text) => postFrame.requestViewSearchPosts(text) onRequestAddMutedWord: (text) => postFrame.requestAddMutedWord(text) + onRequestCopyTagToClipboard: (text) => postFrame.requestCopyTagToClipboard(text) } } } diff --git a/app/qml/view/NotificationListView.qml b/app/qml/view/NotificationListView.qml index 5d4b29e9..7fb86e92 100644 --- a/app/qml/view/NotificationListView.qml +++ b/app/qml/view/NotificationListView.qml @@ -84,6 +84,7 @@ ScrollView { onRequestViewProfile: (did) => notificationListView.requestViewProfile(did) onRequestViewSearchPosts: (text) => notificationListView.requestViewSearchPosts(text) onRequestAddMutedWord: (text) => notificationListView.requestAddMutedWord(text) + onRequestCopyTagToClipboard: (text) => systemTool.copyToClipboard(text) moderationFrame.visible: model.muted userFilterMatched: model.userFilterMatched diff --git a/app/qml/view/PostThreadView.qml b/app/qml/view/PostThreadView.qml index b98b3583..bd3f4080 100644 --- a/app/qml/view/PostThreadView.qml +++ b/app/qml/view/PostThreadView.qml @@ -113,6 +113,7 @@ ColumnLayout { onRequestViewProfile: (did) => postThreadView.requestViewProfile(did) onRequestViewSearchPosts: (text) => postThreadView.requestViewSearchPosts(text) onRequestAddMutedWord: (text) => postThreadView.requestAddMutedWord(text) + onRequestCopyTagToClipboard: (text) => systemTool.copyToClipboard(text) moderationFrame.visible: model.muted userFilterMatched: model.userFilterMatched diff --git a/app/qml/view/TimelineView.qml b/app/qml/view/TimelineView.qml index a31bbcaa..f7b21c41 100644 --- a/app/qml/view/TimelineView.qml +++ b/app/qml/view/TimelineView.qml @@ -108,6 +108,7 @@ ScrollView { onRequestViewProfile: (did) => timelineView.requestViewProfile(did) onRequestViewSearchPosts: (text) => timelineView.requestViewSearchPosts(text) onRequestAddMutedWord: (text) => timelineView.requestAddMutedWord(text) + onRequestCopyTagToClipboard: (text) => systemTool.copyToClipboard(text) moderationFrame.visible: model.muted userFilterMatched: model.userFilterMatched From 670de281c8ee0bf80afba81b86fbfa6a6e1ce424 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Fri, 11 Oct 2024 21:31:50 +0900 Subject: [PATCH 21/24] =?UTF-8?q?=E3=83=AA=E3=83=AA=E3=83=BC=E3=82=B9?= =?UTF-8?q?=E3=83=8E=E3=83=BC=E3=83=88=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/content/docs/release-note.en.md | 1 + web/content/docs/release-note.ja.md | 1 + 2 files changed, 2 insertions(+) diff --git a/web/content/docs/release-note.en.md b/web/content/docs/release-note.en.md index adb6a4cd..c7732c1d 100644 --- a/web/content/docs/release-note.en.md +++ b/web/content/docs/release-note.en.md @@ -10,6 +10,7 @@ description: This is a multi-column Bluesky client. - Add - Add labels set for the account to the post thread + - Added a function to copy hashtags - Update - Change the display format of the profile label - Reduces the amount of data transmitted in real-time feeds diff --git a/web/content/docs/release-note.ja.md b/web/content/docs/release-note.ja.md index 369b34df..809b418b 100644 --- a/web/content/docs/release-note.ja.md +++ b/web/content/docs/release-note.ja.md @@ -10,6 +10,7 @@ description: マルチカラム対応Blueskyクライアント - 追加 - ポストスレッドにアカウントに設定されたラベルを追加 + - ハッシュタグをコピーする機能を追加 - 更新 - プロフィールのラベルの表示方法を変更 - リアルタイムフィードの通信量を軽減 From 8911a369051ee2f4e08423cb73677aa3e5a728d6 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Fri, 11 Oct 2024 21:32:56 +0900 Subject: [PATCH 22/24] =?UTF-8?q?=E7=BF=BB=E8=A8=B3=E3=82=92=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/i18n/app_ja.qm | Bin 42219 -> 42278 bytes app/i18n/app_ja.ts | 21 +++++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/app/i18n/app_ja.qm b/app/i18n/app_ja.qm index 55732027ab158fb39c9809cd2aa43268f924e7d6..0ea89b691c770ea5bc7ce54f911361e484c97a76 100644 GIT binary patch delta 4627 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 delta 4470 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 diff --git a/app/i18n/app_ja.ts b/app/i18n/app_ja.ts index 96a5f649..86e44293 100644 --- a/app/i18n/app_ja.ts +++ b/app/i18n/app_ja.ts @@ -876,17 +876,22 @@ Please recreate AppPassword in the official application. HashTagMenu - + Search %s posts %s を検索 - + Search %s posts by this user このユーザーによる %s を検索 - + + Copy %s + %sをコピー + + + Mute %s posts %s をミュートする @@ -2075,12 +2080,12 @@ Please recreate AppPassword in the official application. NotificationDelegate - + Post from an account you muted. ミュートしているアカウントのポスト - + signed up with your starter pack あなたのスターターパックで登録しました @@ -2212,7 +2217,7 @@ Please recreate AppPassword in the official application. PostDelegate - + Post from an account you muted. ミュートしているアカウントのポスト @@ -2288,7 +2293,7 @@ Please recreate AppPassword in the official application. ポストスレッド - + Quoted content warning 閲覧注意な引用 @@ -3395,7 +3400,7 @@ Why should this message be reviewed? TimelineView - + Quoted content warning 閲覧注意な引用 From a1fc851af1eb9a0749f0a278be2258bb32143519 Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Fri, 11 Oct 2024 22:07:25 +0900 Subject: [PATCH 23/24] =?UTF-8?q?=E3=83=8F=E3=83=83=E3=82=B7=E3=83=A5?= =?UTF-8?q?=E3=82=BF=E3=82=B0=E3=81=AE=E3=83=A1=E3=83=8B=E3=83=A5=E3=83=BC?= =?UTF-8?q?=E3=81=AE=E8=A1=A8=E7=A4=BA=E4=BD=8D=E7=BD=AE=E3=82=92=E8=AA=BF?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/qml/parts/NotificationDelegate.qml | 12 +++++++----- app/qml/parts/PostDelegate.qml | 12 +++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/app/qml/parts/NotificationDelegate.qml b/app/qml/parts/NotificationDelegate.qml index 5cc79676..150e52d7 100644 --- a/app/qml/parts/NotificationDelegate.qml +++ b/app/qml/parts/NotificationDelegate.qml @@ -58,12 +58,12 @@ ClickableFrame { signal requestAddMutedWord(string text) signal requestCopyTagToClipboard(string text) - function openLink(url){ + function openLink(url, x, y){ if(url.indexOf("did:") === 0){ requestViewProfile(url) }else if(url.indexOf("search://") === 0){ - tagMenu.x = recrdTextMouseArea.mouseX - tagMenu.y = recrdTextMouseArea.mouseY + tagMenu.x = x + tagMenu.y = y tagMenu.tagText = url.substring(9) if(tagMenu.tagText.charAt(0) !== "#"){ tagMenu.tagText = "#" + tagMenu.tagText @@ -276,7 +276,7 @@ ClickableFrame { wrapMode: Text.WrapAnywhere font.pointSize: AdjustedValues.f10 lineHeight: 1.3 - onLinkActivated: (url) => openLink(url) + onLinkActivated: (url) => openLink(url, recrdTextMouseArea.mouseX, recrdTextMouseArea.mouseY) onHoveredLinkChanged: displayLink(hoveredLink) HashTagMenu { @@ -361,7 +361,9 @@ ClickableFrame { wrapMode: Text.WrapAnywhere font.pointSize: AdjustedValues.f10 lineHeight: 1.3 - onLinkActivated: (url) => openLink(url) + onLinkActivated: (url) => openLink(url, + quoteRecordRecordText.x + quoteRecordRecordText.width / 4, + quoteRecordRecordText.y + quoteRecordRecordText.height / 2) onHoveredLinkChanged: displayLink(hoveredLink) } ImagePreview { diff --git a/app/qml/parts/PostDelegate.qml b/app/qml/parts/PostDelegate.qml index d1943b76..3dedea2b 100644 --- a/app/qml/parts/PostDelegate.qml +++ b/app/qml/parts/PostDelegate.qml @@ -56,12 +56,12 @@ ClickableFrame { signal requestAddMutedWord(string text) signal requestCopyTagToClipboard(string text) - function openLink(url){ + function openLink(url, x, y){ if(url.indexOf("did:") === 0){ requestViewProfile(url) }else if(url.indexOf("search://") === 0){ - tagMenu.x = recrdTextMouseArea.mouseX - tagMenu.y = recrdTextMouseArea.mouseY + tagMenu.x = x + tagMenu.y = y tagMenu.tagText = url.substring(9) if(tagMenu.tagText.charAt(0) !== "#"){ tagMenu.tagText = "#" + tagMenu.tagText @@ -210,7 +210,7 @@ ClickableFrame { wrapMode: Text.WrapAnywhere font.pointSize: AdjustedValues.f10 lineHeight: 1.3 - onLinkActivated: (url) => openLink(url) + onLinkActivated: (url) => openLink(url, recrdTextMouseArea.mouseX, recrdTextMouseArea.mouseY) onHoveredLinkChanged: displayLink(hoveredLink) HashTagMenu { @@ -280,7 +280,9 @@ ClickableFrame { visible: postFrame.hasQuote && quoteFilterFrame.showContent basisWidth: bodyLayout.basisWidth - onOpenLink: (url) => postFrame.openLink(url) + onOpenLink: (url) => postFrame.openLink(url, + quoteRecordFrame.x + quoteRecordFrame.width / 4, + quoteRecordFrame.y + quoteRecordFrame.height / 2) onDisplayLink: (url) => postFrame.displayLink(url) } Frame { From 3efc9dad75d7ca4e21650bfeb925b6fcd7be918c Mon Sep 17 00:00:00 2001 From: Takayuki Orito Date: Sat, 12 Oct 2024 10:34:28 +0900 Subject: [PATCH 24/24] =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=B3=E6=83=85=E5=A0=B1=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/main.cpp | 2 +- web/content/docs/release-note.en.md | 2 ++ web/content/docs/release-note.ja.md | 2 ++ web/layouts/shortcodes/download_link.html | 8 ++++---- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/app/main.cpp b/app/main.cpp index e29cd2b6..070d4e58 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -91,7 +91,7 @@ int main(int argc, char *argv[]) app.setOrganizationName(QStringLiteral("relog")); app.setOrganizationDomain(QStringLiteral("hagoromo.relog.tech")); app.setApplicationName(QStringLiteral("Hagoromo")); - app.setApplicationVersion(QStringLiteral("0.38.0")); + app.setApplicationVersion(QStringLiteral("0.39.0")); #ifndef HAGOROMO_RELEASE_BUILD app.setApplicationVersion(app.applicationVersion() + "d"); #endif diff --git a/web/content/docs/release-note.en.md b/web/content/docs/release-note.en.md index c7732c1d..fcf8d593 100644 --- a/web/content/docs/release-note.en.md +++ b/web/content/docs/release-note.en.md @@ -8,6 +8,8 @@ description: This is a multi-column Bluesky client. ## 2024 +### v0.39.0 - 2024/10/12 + - Add - Add labels set for the account to the post thread - Added a function to copy hashtags diff --git a/web/content/docs/release-note.ja.md b/web/content/docs/release-note.ja.md index 809b418b..378f76a9 100644 --- a/web/content/docs/release-note.ja.md +++ b/web/content/docs/release-note.ja.md @@ -8,6 +8,8 @@ description: マルチカラム対応Blueskyクライアント ## 2024 +### v0.39.0 - 2024/10/12 + - 追加 - ポストスレッドにアカウントに設定されたラベルを追加 - ハッシュタグをコピーする機能を追加 diff --git a/web/layouts/shortcodes/download_link.html b/web/layouts/shortcodes/download_link.html index 490e5959..61421fac 100644 --- a/web/layouts/shortcodes/download_link.html +++ b/web/layouts/shortcodes/download_link.html @@ -1,9 +1,9 @@