From 3a574cf4e28a8e788e85d6bd88b0582d4016e210 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 19:21:25 +0000 Subject: [PATCH 01/36] Update locale --- locales/en-US.yml | 2 ++ locales/ja-JP.yml | 2 ++ 2 files changed, 4 insertions(+) diff --git a/locales/en-US.yml b/locales/en-US.yml index c6c442df7c..10a9fca3bd 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1114,6 +1114,8 @@ isPatron: "Calckey Patron" reactionPickerSkinTone: "Preferred emoji skin tone" enableServerMachineStats: "Enable server hardware statistics" enableIdenticonGeneration: "Enable Identicon generation" +showPopup: "Notify users about this announcement with a popup" +isGoodNews: "This is a good news" _sensitiveMediaDetection: description: "Reduces the effort of server moderation through automatically recognizing diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 9f2f825e55..e128044289 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -980,6 +980,8 @@ preventAiLearningDescription: "投稿したノート、添付した画像など noGraze: "ブラウザの拡張機能「Graze for Mastodon」は、Calckeyの動作を妨げるため、無効にしてください。" enableServerMachineStats: "サーバーのマシン情報を公開する" enableIdenticonGeneration: "ユーザーごとのIdenticon生成を有効にする" +showPopup: "ポップアップを表示してユーザーに知らせる" +isGoodNews: "これは良いニュースです" _sensitiveMediaDetection: description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てられます。サーバーの負荷が少し増えます。" From 75b352b7213d23ba5fd1b1e65ea74f7150a8fbf9 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 19:48:20 +0000 Subject: [PATCH 02/36] Add showPopup, isGoodNews & Update API --- .../1688845537045-announcement-popup.js | 21 +++++++++++++++++++ .../src/models/entities/announcement.ts | 10 +++++++++ .../endpoints/admin/announcements/create.ts | 14 +++++++++++++ .../api/endpoints/admin/announcements/list.ts | 12 +++++++++++ .../endpoints/admin/announcements/update.ts | 4 ++++ .../src/server/api/endpoints/announcements.ts | 10 +++++++++ 6 files changed, 71 insertions(+) create mode 100644 packages/backend/migration/1688845537045-announcement-popup.js diff --git a/packages/backend/migration/1688845537045-announcement-popup.js b/packages/backend/migration/1688845537045-announcement-popup.js new file mode 100644 index 0000000000..196590d3e3 --- /dev/null +++ b/packages/backend/migration/1688845537045-announcement-popup.js @@ -0,0 +1,21 @@ +export class AnnouncementPopup1688845537045 { + name = "AnnouncementPopup1688845537045"; + + async up(queryRunner) { + await queryRunner.query( + `ALTER TABLE "announcement" ADD "showPopup" boolean NOT NULL DEFAULT false`, + ); + await queryRunner.query( + `ALTER TABLE "announcement" ADD "isGoodNews" boolean NOT NULL DEFAULT false`, + ); + } + + async down(queryRunner) { + await queryRunner.query( + `ALTER TABLE "announcement" DROP COLUMN "isGoodNews"`, + ); + await queryRunner.query( + `ALTER TABLE "announcement" DROP COLUMN "showPopup"`, + ); + } +} diff --git a/packages/backend/src/models/entities/announcement.ts b/packages/backend/src/models/entities/announcement.ts index 1939604b97..7872c0fe1c 100644 --- a/packages/backend/src/models/entities/announcement.ts +++ b/packages/backend/src/models/entities/announcement.ts @@ -36,6 +36,16 @@ export class Announcement { }) public imageUrl: string | null; + @Column("boolean", { + default: false, + }) + public showPopup: boolean; + + @Column("boolean", { + default: false, + }) + public isGoodNews: boolean; + constructor(data: Partial) { if (data == null) return; diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/create.ts b/packages/backend/src/server/api/endpoints/admin/announcements/create.ts index a532b6677f..754cc6c893 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/create.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/create.ts @@ -47,6 +47,16 @@ export const meta = { optional: false, nullable: true, }, + showPopup: { + type: "boolean", + optional: true, + nullable: false, + }, + isGoodNews: { + type: "boolean", + optional: true, + nullable: false, + }, }, }, } as const; @@ -57,6 +67,8 @@ export const paramDef = { title: { type: "string", minLength: 1 }, text: { type: "string", minLength: 1 }, imageUrl: { type: "string", nullable: true, minLength: 1 }, + showPopup: { type: "boolean" }, + isGoodNews: { type: "boolean" }, }, required: ["title", "text", "imageUrl"], } as const; @@ -69,6 +81,8 @@ export default define(meta, paramDef, async (ps) => { title: ps.title, text: ps.text, imageUrl: ps.imageUrl, + showPopup: ps.showPopup ?? false, + isGoodNews: ps.isGoodNews ?? false, }).then((x) => Announcements.findOneByOrFail(x.identifiers[0])); return Object.assign({}, announcement, { diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts index fc5b020706..e96517c68e 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/list.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/list.ts @@ -57,6 +57,16 @@ export const meta = { optional: false, nullable: false, }, + showPopup: { + type: "boolean", + optional: true, + nullable: false, + }, + isGoodNews: { + type: "boolean", + optional: true, + nullable: false, + }, }, }, }, @@ -100,5 +110,7 @@ export default define(meta, paramDef, async (ps) => { text: announcement.text, imageUrl: announcement.imageUrl, reads: reads.get(announcement)!, + showPopup: announcement.showPopup, + isGoodNews: announcement.isGoodNews, })); }); diff --git a/packages/backend/src/server/api/endpoints/admin/announcements/update.ts b/packages/backend/src/server/api/endpoints/admin/announcements/update.ts index 35e64f2819..616b94d699 100644 --- a/packages/backend/src/server/api/endpoints/admin/announcements/update.ts +++ b/packages/backend/src/server/api/endpoints/admin/announcements/update.ts @@ -24,6 +24,8 @@ export const paramDef = { title: { type: "string", minLength: 1 }, text: { type: "string", minLength: 1 }, imageUrl: { type: "string", nullable: true, minLength: 1 }, + showPopup: { type: "boolean" }, + isGoodNews: { type: "boolean" }, }, required: ["id", "title", "text", "imageUrl"], } as const; @@ -38,5 +40,7 @@ export default define(meta, paramDef, async (ps, me) => { title: ps.title, text: ps.text, imageUrl: ps.imageUrl, + showPopup: ps.showPopup ?? false, + isGoodNews: ps.isGoodNews ?? false, }); }); diff --git a/packages/backend/src/server/api/endpoints/announcements.ts b/packages/backend/src/server/api/endpoints/announcements.ts index 00634cc421..1bab61ba2c 100644 --- a/packages/backend/src/server/api/endpoints/announcements.ts +++ b/packages/backend/src/server/api/endpoints/announcements.ts @@ -56,6 +56,16 @@ export const meta = { optional: true, nullable: false, }, + showPopup: { + type: "boolean", + optional: false, + nullable: false, + }, + isGoodNews: { + type: "boolean", + optional: false, + nullable: false, + }, }, }, }, From 478be7a3aed5e4f9d31686ea3332e2f2b9fe88ea Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 19:55:38 +0000 Subject: [PATCH 03/36] Create MkAnnouncement component --- .../client/src/components/MkAnnouncement.vue | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 packages/client/src/components/MkAnnouncement.vue diff --git a/packages/client/src/components/MkAnnouncement.vue b/packages/client/src/components/MkAnnouncement.vue new file mode 100644 index 0000000000..f95479a7f4 --- /dev/null +++ b/packages/client/src/components/MkAnnouncement.vue @@ -0,0 +1,83 @@ + + + + + From aeb1f9c99362b8c269a54513dea6222a9e8222fb Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 19:57:26 +0000 Subject: [PATCH 04/36] chore: Use css module --- packages/client/src/pages/admin/announcements.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client/src/pages/admin/announcements.vue b/packages/client/src/pages/admin/announcements.vue index 9853158deb..726e521abe 100644 --- a/packages/client/src/pages/admin/announcements.vue +++ b/packages/client/src/pages/admin/announcements.vue @@ -7,7 +7,7 @@ :display-back-button="true" /> -
+
- From c47ec377c7a1a17f7914babcb44474e3028e9dc0 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 20:01:16 +0000 Subject: [PATCH 05/36] Add showPopup, isGoodNews to announcement setting UI --- packages/client/src/pages/admin/announcements.vue | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/client/src/pages/admin/announcements.vue b/packages/client/src/pages/admin/announcements.vue index 726e521abe..95ad5a8a28 100644 --- a/packages/client/src/pages/admin/announcements.vue +++ b/packages/client/src/pages/admin/announcements.vue @@ -22,6 +22,17 @@ + {{ i18n.ts.showPopup }} + {{ i18n.ts.isGoodNews }}

{{ i18n.t("nUsersRead", { n: announcement.reads }) @@ -57,6 +68,7 @@ import {} from "vue"; import MkButton from "@/components/MkButton.vue"; import MkInput from "@/components/form/input.vue"; +import MkSwitch from "@/components/form/switch.vue"; import MkTextarea from "@/components/form/textarea.vue"; import * as os from "@/os"; import { i18n } from "@/i18n"; @@ -74,6 +86,8 @@ function add() { title: "", text: "", imageUrl: null, + showPopup: false, + isGoodNews: false, }); } From f7062a03fe53ccd8a86f5ef596b69fddb5421574 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 20:09:40 +0000 Subject: [PATCH 06/36] Show popups at client init --- packages/client/src/init.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/client/src/init.ts b/packages/client/src/init.ts index 1c68b87c95..1b85ef9c63 100644 --- a/packages/client/src/init.ts +++ b/packages/client/src/init.ts @@ -36,7 +36,7 @@ import { version, ui, lang, host } from "@/config"; import { applyTheme } from "@/scripts/theme"; import { isDeviceDarkmode } from "@/scripts/is-device-darkmode"; import { i18n } from "@/i18n"; -import { confirm, alert, post, popup, toast } from "@/os"; +import { confirm, alert, post, popup, toast, api } from "@/os"; import { stream } from "@/stream"; import * as sound from "@/scripts/sound"; import { $i, refreshAccount, login, updateAccount, signout } from "@/account"; @@ -272,6 +272,25 @@ function checkForSplash() { } } + if ($i) { + api("announcements", { withUnreads: true }) + .then((announcements) => { + console.log(announcements); + announcements.forEach((announcement) => { + if (announcement.showPopup && announcement.isRead === false) + popup( + defineAsyncComponent( + () => import("@/components/MkAnnouncement.vue"), + ), + { announcement: announcement }, + {}, + "closed", + ); + }); + }) + .catch((err) => console.log(err)); + } + // NOTE: この処理は必ず↑のクライアント更新時処理より後に来ること(テーマ再構築のため) watch( defaultStore.reactiveState.darkMode, From e7ccbb030defc3a476181ef97941e0fec21cdff6 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 20:15:08 +0000 Subject: [PATCH 07/36] Fix isRead not being saved on closing popups --- packages/client/src/components/MkAnnouncement.vue | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/client/src/components/MkAnnouncement.vue b/packages/client/src/components/MkAnnouncement.vue index f95479a7f4..205709d985 100644 --- a/packages/client/src/components/MkAnnouncement.vue +++ b/packages/client/src/components/MkAnnouncement.vue @@ -17,7 +17,10 @@ :class="$style.gotIt" primary full - @click="$refs.modal.close() && markAsRead()" + @click=" + $refs.modal.close(); + markAsRead(); + " >{{ i18n.ts.gotIt }}

@@ -42,7 +45,7 @@ const { id, text, title, imageUrl, isGoodNews } = props.announcement; const modal = shallowRef>(); function markAsRead() { - os.api("i/read-announcement", { announcementId: props.announcement.id }); + os.api("i/read-announcement", { announcementId: id }); } From d8a94fc70790dba68e17cbf5ec35a682be258d13 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 20:22:04 +0000 Subject: [PATCH 08/36] oops (remove debug logs) --- packages/client/src/init.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/client/src/init.ts b/packages/client/src/init.ts index 1b85ef9c63..a0e99b9dcb 100644 --- a/packages/client/src/init.ts +++ b/packages/client/src/init.ts @@ -275,7 +275,6 @@ function checkForSplash() { if ($i) { api("announcements", { withUnreads: true }) .then((announcements) => { - console.log(announcements); announcements.forEach((announcement) => { if (announcement.showPopup && announcement.isRead === false) popup( From 20fbb4f57e2dce25d96cef9564874edd80d29a54 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 20:31:18 +0000 Subject: [PATCH 09/36] Don't show more then three announcement popups (because it can be annoying for new users) --- packages/client/src/init.ts | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/packages/client/src/init.ts b/packages/client/src/init.ts index a0e99b9dcb..ff4dee309e 100644 --- a/packages/client/src/init.ts +++ b/packages/client/src/init.ts @@ -273,19 +273,26 @@ function checkForSplash() { } if ($i) { - api("announcements", { withUnreads: true }) + api("announcements", { withUnreads: true, limit: 10 }) .then((announcements) => { - announcements.forEach((announcement) => { - if (announcement.showPopup && announcement.isRead === false) - popup( - defineAsyncComponent( - () => import("@/components/MkAnnouncement.vue"), - ), - { announcement: announcement }, - {}, - "closed", - ); + const unreadAnnouncements = announcements.filter((item) => { + return !item.isRead; }); + if (unreadAnnouncements.length > 3) { + // TODO: navigate to the announcements page when there are too many unreads + } else { + unreadAnnouncements.forEach((item) => { + if (item.showPopup) + popup( + defineAsyncComponent( + () => import("@/components/MkAnnouncement.vue"), + ), + { announcement: item }, + {}, + "closed", + ); + }); + } }) .catch((err) => console.log(err)); } From 8b79f59d8de4d28d9af1d79131451ac0bd7c201b Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 21:02:11 +0000 Subject: [PATCH 10/36] Navigate to /announcements if there are more than three unreads --- locales/en-US.yml | 1 + locales/ja-JP.yml | 1 + .../src/components/MkManyAnnouncements.vue | 67 +++++++++++++++++++ packages/client/src/init.ts | 14 +++- 4 files changed, 81 insertions(+), 2 deletions(-) create mode 100644 packages/client/src/components/MkManyAnnouncements.vue diff --git a/locales/en-US.yml b/locales/en-US.yml index 10a9fca3bd..8844cf9be8 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1116,6 +1116,7 @@ enableServerMachineStats: "Enable server hardware statistics" enableIdenticonGeneration: "Enable Identicon generation" showPopup: "Notify users about this announcement with a popup" isGoodNews: "This is a good news" +youHaveUnreadAnnouncements: "You have unread announcements" _sensitiveMediaDetection: description: "Reduces the effort of server moderation through automatically recognizing diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 1d23fc8cfe..873eed1cf3 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -982,6 +982,7 @@ enableServerMachineStats: "サーバーのマシン情報を公開する" enableIdenticonGeneration: "ユーザーごとのIdenticon生成を有効にする" showPopup: "ポップアップを表示してユーザーに知らせる" isGoodNews: "これは良いニュースです" +youHaveUnreadAnnouncements: "未読のお知らせがあります" _sensitiveMediaDetection: description: "機械学習を使って自動でセンシティブなメディアを検出し、モデレーションに役立てられます。サーバーの負荷が少し増えます。" diff --git a/packages/client/src/components/MkManyAnnouncements.vue b/packages/client/src/components/MkManyAnnouncements.vue new file mode 100644 index 0000000000..30cdcf99e8 --- /dev/null +++ b/packages/client/src/components/MkManyAnnouncements.vue @@ -0,0 +1,67 @@ + + + + + diff --git a/packages/client/src/init.ts b/packages/client/src/init.ts index ff4dee309e..2b99dd4d5f 100644 --- a/packages/client/src/init.ts +++ b/packages/client/src/init.ts @@ -272,14 +272,24 @@ function checkForSplash() { } } - if ($i) { + if ( + $i && + !["/announcements", "/announcements/"].includes(window.location.pathname) + ) { api("announcements", { withUnreads: true, limit: 10 }) .then((announcements) => { const unreadAnnouncements = announcements.filter((item) => { return !item.isRead; }); if (unreadAnnouncements.length > 3) { - // TODO: navigate to the announcements page when there are too many unreads + popup( + defineAsyncComponent( + () => import("@/components/MkManyAnnouncements.vue"), + ), + {}, + {}, + "closed", + ); } else { unreadAnnouncements.forEach((item) => { if (item.showPopup) From ac9774c1e625818f842889eebae6cf20b41abcc2 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 21:17:13 +0000 Subject: [PATCH 11/36] Refactor MkAnnouncement --- .../client/src/components/MkAnnouncement.vue | 41 +++++++------------ 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/packages/client/src/components/MkAnnouncement.vue b/packages/client/src/components/MkAnnouncement.vue index 205709d985..89bd734cd5 100644 --- a/packages/client/src/components/MkAnnouncement.vue +++ b/packages/client/src/components/MkAnnouncement.vue @@ -8,21 +8,13 @@ attached image - {{ i18n.ts.gotIt }} + {{ + i18n.ts.gotIt + }}
@@ -32,7 +24,6 @@ import { shallowRef } from "vue"; import MkModal from "@/components/MkModal.vue"; import MkSparkle from "@/components/MkSparkle.vue"; import MkButton from "@/components/MkButton.vue"; -import { version } from "@/config"; import { i18n } from "@/i18n"; import * as os from "@/os"; @@ -44,9 +35,10 @@ const { id, text, title, imageUrl, isGoodNews } = props.announcement; const modal = shallowRef>(); -function markAsRead() { +const gotIt = () => { + modal.value.close(); os.api("i/read-announcement", { announcementId: id }); -} +}; From 2f4f3a3e02b55e42f7b3756676a2b3c7e39ee346 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 21:21:16 +0000 Subject: [PATCH 12/36] Remove unnecessary imports --- .../src/components/MkManyAnnouncements.vue | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/packages/client/src/components/MkManyAnnouncements.vue b/packages/client/src/components/MkManyAnnouncements.vue index 30cdcf99e8..5c8b225dee 100644 --- a/packages/client/src/components/MkManyAnnouncements.vue +++ b/packages/client/src/components/MkManyAnnouncements.vue @@ -19,7 +19,6 @@ import { shallowRef } from "vue"; import MkModal from "@/components/MkModal.vue"; import MkButton from "@/components/MkButton.vue"; -import { version } from "@/config"; import { i18n } from "@/i18n"; import * as os from "@/os"; @@ -45,23 +44,10 @@ const checkAnnouncements = () => { .title { font-weight: bold; -} - -.version { - margin: 1em 0; -} - -.image { - max-width: 500px; + margin: 0; } .gotIt { margin: 8px 0 0 0; } - -.releaseNotes { - > img { - border-radius: 10px; - } -} From cb6df7fe25a09c3b0b33327f4f05b47d50d7c671 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 21:47:06 +0000 Subject: [PATCH 13/36] Don't show announcement popups if the tutorial isn't completed --- packages/client/src/init.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/client/src/init.ts b/packages/client/src/init.ts index 2b99dd4d5f..11b9a2edac 100644 --- a/packages/client/src/init.ts +++ b/packages/client/src/init.ts @@ -274,6 +274,7 @@ function checkForSplash() { if ( $i && + defaultStore.state.tutorial === -1 && !["/announcements", "/announcements/"].includes(window.location.pathname) ) { api("announcements", { withUnreads: true, limit: 10 }) From 12f6c57ed150612f567305f1f72282fc949bce41 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 22:16:40 +0000 Subject: [PATCH 14/36] Update locale --- locales/ja-JP.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 873eed1cf3..c3cd7b4629 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -981,7 +981,7 @@ noGraze: "ブラウザの拡張機能「Graze for Mastodon」は、Calckeyの動 enableServerMachineStats: "サーバーのマシン情報を公開する" enableIdenticonGeneration: "ユーザーごとのIdenticon生成を有効にする" showPopup: "ポップアップを表示してユーザーに知らせる" -isGoodNews: "これは良いニュースです" +isGoodNews: "これは良いお知らせです" youHaveUnreadAnnouncements: "未読のお知らせがあります" _sensitiveMediaDetection: From b5585c1e98cb26baba8d75c91ccacd9fa47e2b01 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 22:29:36 +0000 Subject: [PATCH 15/36] better locale & style --- locales/en-US.yml | 4 ++-- locales/ja-JP.yml | 2 +- packages/client/src/components/MkAnnouncement.vue | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/locales/en-US.yml b/locales/en-US.yml index 8844cf9be8..b7248e033f 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1114,8 +1114,8 @@ isPatron: "Calckey Patron" reactionPickerSkinTone: "Preferred emoji skin tone" enableServerMachineStats: "Enable server hardware statistics" enableIdenticonGeneration: "Enable Identicon generation" -showPopup: "Notify users about this announcement with a popup" -isGoodNews: "This is a good news" +showPopup: "Notify users with popup" +showWithSparkles: "Show with sparkles" youHaveUnreadAnnouncements: "You have unread announcements" _sensitiveMediaDetection: diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index c3cd7b4629..e0f1421171 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -981,7 +981,7 @@ noGraze: "ブラウザの拡張機能「Graze for Mastodon」は、Calckeyの動 enableServerMachineStats: "サーバーのマシン情報を公開する" enableIdenticonGeneration: "ユーザーごとのIdenticon生成を有効にする" showPopup: "ポップアップを表示してユーザーに知らせる" -isGoodNews: "これは良いお知らせです" +showWithSparcles: "タイトルをキラキラさせる" youHaveUnreadAnnouncements: "未読のお知らせがあります" _sensitiveMediaDetection: diff --git a/packages/client/src/components/MkAnnouncement.vue b/packages/client/src/components/MkAnnouncement.vue index 89bd734cd5..eff5ae3bb1 100644 --- a/packages/client/src/components/MkAnnouncement.vue +++ b/packages/client/src/components/MkAnnouncement.vue @@ -2,7 +2,7 @@
- {{ title }} + {{ title }}

{{ title }}

@@ -54,6 +54,7 @@ const gotIt = () => { border-radius: var(--radius); > img { + border-radius: 10px; max-height: 100%; max-width: 100%; } From fb8c2b131031df32c8c794cbc56312da51448e28 Mon Sep 17 00:00:00 2001 From: naskya Date: Sat, 8 Jul 2023 22:37:15 +0000 Subject: [PATCH 16/36] fix --- locales/ja-JP.yml | 2 +- packages/client/src/components/MkAnnouncement.vue | 2 +- packages/client/src/pages/admin/announcements.vue | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index e0f1421171..95fb7bcf88 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -981,7 +981,7 @@ noGraze: "ブラウザの拡張機能「Graze for Mastodon」は、Calckeyの動 enableServerMachineStats: "サーバーのマシン情報を公開する" enableIdenticonGeneration: "ユーザーごとのIdenticon生成を有効にする" showPopup: "ポップアップを表示してユーザーに知らせる" -showWithSparcles: "タイトルをキラキラさせる" +showWithSparkles: "タイトルをキラキラさせる" youHaveUnreadAnnouncements: "未読のお知らせがあります" _sensitiveMediaDetection: diff --git a/packages/client/src/components/MkAnnouncement.vue b/packages/client/src/components/MkAnnouncement.vue index eff5ae3bb1..24bf886dd8 100644 --- a/packages/client/src/components/MkAnnouncement.vue +++ b/packages/client/src/components/MkAnnouncement.vue @@ -2,7 +2,7 @@
- {{ title }} + {{ title }}

{{ title }}

diff --git a/packages/client/src/pages/admin/announcements.vue b/packages/client/src/pages/admin/announcements.vue index 95ad5a8a28..b2172b307b 100644 --- a/packages/client/src/pages/admin/announcements.vue +++ b/packages/client/src/pages/admin/announcements.vue @@ -31,7 +31,7 @@ v-if="announcement.showPopup" v-model="announcement.isGoodNews" class="_formBlock" - >{{ i18n.ts.isGoodNews }}{{ i18n.ts.showWithSparkles }}

{{ From ddff273a427ad93127dfcdda704e691d3a95ef9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aliberk=20Sand=C4=B1k=C3=A7=C4=B1?= Date: Fri, 7 Jul 2023 14:37:53 +0000 Subject: [PATCH 17/36] chore: Translated using Weblate (Turkish) Currently translated at 3.9% (71 of 1816 strings) Translation: Calckey/locales Translate-URL: https://hosted.weblate.org/projects/calckey/locales/tr/ --- locales/tr-TR.yml | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/locales/tr-TR.yml b/locales/tr-TR.yml index 7dee4fd302..a0a45f34cd 100644 --- a/locales/tr-TR.yml +++ b/locales/tr-TR.yml @@ -1,9 +1,12 @@ ---- _lang_: "Türkçe" -introMisskey: "Açık kaynaklı bir dağıtılmış mikroblog hizmeti olan Calckey'e hoş geldiniz.\nMisskey, neler olup bittiğini paylaşmak ve herkese sizden bahsetmek için \"notlar\" oluşturmanıza olanak tanıyan, açık kaynaklı, dağıtılmış bir mikroblog hizmetidir.\nHerkesin notlarına kendi tepkilerinizi hızlıca eklemek için \"Tepkiler\" özelliğini de kullanabilirsiniz👍.\nYeni bir dünyayı keşfedin🚀." +introMisskey: "Açık kaynaklı bir dağıtılmış mikroblog hizmeti olan Calckey'e hoş geldiniz.\n + Misskey, neler olup bittiğini paylaşmak ve herkese sizden bahsetmek için \"notlar\"\ + \ oluşturmanıza olanak tanıyan, açık kaynaklı, dağıtılmış bir mikroblog hizmetidir.\n + Herkesin notlarına kendi tepkilerinizi hızlıca eklemek için \"Tepkiler\" özelliğini + de kullanabilirsiniz👍.\nYeni bir dünyayı keşfedin🚀." monthAndDay: "{month}Ay {day}Gün" search: "Arama" -notifications: "Bildirim" +notifications: "Bildirimler" username: "Kullanıcı Adı" password: "Şifre" forgotPassword: "şifremi unuttum" @@ -11,7 +14,7 @@ ok: "TAMAM" gotIt: "Anladım" cancel: "İptal" enterUsername: "Kullanıcı adınızı giriniz" -noNotes: "Notlar mevcut değil." +noNotes: "Gönderiler mevcut değil." noNotifications: "Bildirim bulunmuyor" settings: "Ayarlar" basicSettings: "Temel Ayarlar" @@ -37,7 +40,8 @@ copyContent: "İçeriği kopyala" copyLink: "Bağlantıyı Kopyala" delete: "Sil" deleteAndEdit: "Sil ve yeniden düzenle" -deleteAndEditConfirm: "Bu notu silip yeniden düzenlemek istiyor musunuz? Bu nota ilişkin tüm Tepkiler, Yeniden Notlar ve Yanıtlar da silinecektir." +deleteAndEditConfirm: "Bu gönderiyi silip yeniden düzenlemek istiyor musunuz? Bu gönderiye + ilişkin tüm tepkiler, destekler ve yanıtlar silinecektir." addToList: "Listeye ekle" sendMessage: "Mesaj Gönder" copyUsername: "Kullanıcı Adını Kopyala" @@ -61,3 +65,19 @@ _deck: _columns: notifications: "Bildirim" tl: "Zaman çizelgesi" +searchPlaceholder: Calckey'de Ara +reply: Yanıtla +jumpToPrevious: Öncekini görüntüle +deleted: Silindi +editNote: Notu düzenle +noThankYou: Hayır, teşekkürler +addInstance: Bir sunucu ekle +cantFavorite: Favorilere eklenemedi. +edited: '{date} tarihinde ve {time} vaktinde düzenlendi' +loggingIn: Giriş Yapılıyor +save: Kaydet +headlineMisskey: Sonsuza kadar ücretsiz, açık kaynak kodlu, merkeziyetsiz sosyal medya + platformu! 🚀 +loadMore: Daha fazla yükle +instance: Sunucu +fetchingAsApObject: Fedevren'den çekiliyor From a79ddb5a242597c4ab74c75e7907d2a1392bd26a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=AA=A0=E8=AA=A0-ChengCheng?= Date: Sat, 8 Jul 2023 11:12:43 +0000 Subject: [PATCH 18/36] chore: Translated using Weblate (Chinese (Traditional)) Currently translated at 95.0% (1726 of 1816 strings) Translation: Calckey/locales Translate-URL: https://hosted.weblate.org/projects/calckey/locales/zh_Hant/ --- locales/zh-TW.yml | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index 3e5b6690ad..2803d7846c 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -702,7 +702,8 @@ onlineUsersCount: "{n}人正在線上" nUsers: "{n}用戶" nNotes: "{n}貼文" sendErrorReports: "傳送錯誤報告" -sendErrorReportsDescription: "啟用後,問題報告將傳送至Calckey開發者以提升軟體品質。\n問題報告可能包括OS版本,瀏覽器類型,行為歷史記錄等。" +sendErrorReportsDescription: "開啟後,錯誤出現時將會與 Calckey 分享詳細紀錄,對於 Calckey 的開發會有非常大的幫助。\n + 這將包括您的操作系統版本、使用的瀏覽器、您在 Calckey 中的活動等資料。" myTheme: "我的佈景主題" backgroundColor: "背景" accentColor: "重點色彩" @@ -862,7 +863,7 @@ check: "檢查" driveCapOverrideLabel: "更改這個使用者的雲端硬碟容量上限" driveCapOverrideCaption: "如果指定0以下的值,就會被取消。" requireAdminForView: "必須以管理者帳號登入才可以檢視。" -isSystemAccount: "由系統自動建立與管理的帳號。" +isSystemAccount: "該帳號由系統自動創建並運行。 千千萬萬不要審核、編輯、刪除或以其他方式修改此帳戶,否則可能會破壞您的伺服器。" typeToConfirm: "要執行這項操作,請輸入 {x}" deleteAccount: "刪除帳號" document: "文件" @@ -1855,3 +1856,14 @@ hiddenTagsDescription: '列出您希望隱藏趨勢和探索的主題標籤( userSaysSomethingReasonQuote: '{name} 引用了一篇包含 {reason} 的貼文' silencedInstancesDescription: 列出您想要靜音的伺服器的網址。 您列出的伺服器內的帳戶將被視為“沉默”,只能發出追隨請求,如果不追隨則不能提及本地帳戶。 這不會影響被阻止的伺服器。 +video: 影片 +audio: 音訊 +sendPushNotificationReadMessageCaption: 包含文本 “{emptyPushNotificationMessage}” 的通知將顯示一小段時間。 + 這可能會增加您設備的電池使用量(如果適用)。 +channelFederationWarn: 頻道功能尚未與聯邦宇宙連動 +swipeOnMobile: 允許在頁面之間滑動 +sendPushNotificationReadMessage: 閱讀相關通知或消息後刪除推送通知 +image: 圖片 +seperateRenoteQuote: 分別獨立的轉傳及引用按鈕 +clipsDesc: 摘錄就像一個可以分享的書籤。 你可以從每個貼文的菜單創建新摘錄或將貼文加入已有的摘錄。 +noteId: 貼文 ID From 68ec7b3d94241a2376755acf566c0c6376301f0b Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sat, 8 Jul 2023 18:48:59 +0200 Subject: [PATCH 19/36] [mastodon-client] remove reactions reply --- .../server/api/mastodon/endpoints/status.ts | 84 +------------------ 1 file changed, 1 insertion(+), 83 deletions(-) diff --git a/packages/backend/src/server/api/mastodon/endpoints/status.ts b/packages/backend/src/server/api/mastodon/endpoints/status.ts index 3c58cf3a42..76057ef0a2 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/status.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/status.ts @@ -123,27 +123,7 @@ export function apiStatusMastodon(router: Router): void { id, convertTimelinesArgsId(limitToInt(ctx.query as any)), ); - const status = await client.getStatus(id); - let reqInstance = axios.create({ - headers: { - Authorization: ctx.headers.authorization, - }, - }); - const reactionsAxios = await reqInstance.get( - `${BASE_URL}/api/notes/reactions?noteId=${id}`, - ); - const reactions: IReaction[] = reactionsAxios.data; - const text = reactions - .map((r) => `${r.type.replace("@.", "")} ${r.user.username}`) - .join("
"); - data.data.descendants.unshift( - statusModel( - status.data.id, - status.data.account.id, - status.data.emojis, - text, - ), - ); + data.data.ancestors = data.data.ancestors.map((status) => convertStatus(status), ); @@ -456,65 +436,3 @@ async function getFirstReaction( return react; } } - -export function statusModel( - id: string | null, - acctId: string | null, - emojis: MastodonEntity.Emoji[], - content: string, -) { - const now = new Date().toISOString(); - return { - id: "9atm5frjhb", - uri: "/static-assets/transparent.png", // "" - url: "/static-assets/transparent.png", // "", - account: { - id: "9arzuvv0sw", - username: "Reactions", - acct: "Reactions", - display_name: "Reactions to this post", - locked: false, - created_at: now, - followers_count: 0, - following_count: 0, - statuses_count: 0, - note: "", - url: "/static-assets/transparent.png", - avatar: "/static-assets/badges/info.png", - avatar_static: "/static-assets/badges/info.png", - header: "/static-assets/transparent.png", // "" - header_static: "/static-assets/transparent.png", // "" - emojis: [], - fields: [], - moved: null, - bot: false, - }, - in_reply_to_id: id, - in_reply_to_account_id: acctId, - reblog: null, - content: `

${content}

`, - plain_content: null, - created_at: now, - emojis: emojis, - replies_count: 0, - reblogs_count: 0, - favourites_count: 0, - favourited: false, - reblogged: false, - muted: false, - sensitive: false, - spoiler_text: "", - visibility: "public" as const, - media_attachments: [], - mentions: [], - tags: [], - card: null, - poll: null, - application: null, - language: null, - pinned: false, - emoji_reactions: [], - bookmarked: false, - quote: null, - }; -} From 2775ab324e5856bdac278674d11a03157919a367 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sat, 8 Jul 2023 21:31:45 +0200 Subject: [PATCH 20/36] [mastodon-client] send actual default post privacy instead of fallback value --- .../api/endpoints/i/registry/get-unsecure.ts | 2 +- .../server/api/mastodon/endpoints/account.ts | 2 +- packages/megalodon/src/misskey.ts | 17 +++++++++++++++++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/server/api/endpoints/i/registry/get-unsecure.ts b/packages/backend/src/server/api/endpoints/i/registry/get-unsecure.ts index f98c6c929f..a9bcf69351 100644 --- a/packages/backend/src/server/api/endpoints/i/registry/get-unsecure.ts +++ b/packages/backend/src/server/api/endpoints/i/registry/get-unsecure.ts @@ -33,7 +33,7 @@ export const paramDef = { } as const; export default define(meta, paramDef, async (ps, user) => { - if (ps.key !== "reactions") return; + if (ps.key !== "reactions" && ps.key !== "defaultNoteVisibility") return; const query = RegistryItems.createQueryBuilder("item") .where("item.domain IS NULL") .andWhere("item.userId = :userId", { userId: user.id }) diff --git a/packages/backend/src/server/api/mastodon/endpoints/account.ts b/packages/backend/src/server/api/mastodon/endpoints/account.ts index 3fb1c9cbe4..5d0abdedd6 100644 --- a/packages/backend/src/server/api/mastodon/endpoints/account.ts +++ b/packages/backend/src/server/api/mastodon/endpoints/account.ts @@ -48,7 +48,7 @@ export function apiAccountMastodon(router: Router): void { acct.source = { note: acct.note, fields: acct.fields, - privacy: "public", + privacy: await client.getDefaultPostPrivacy(), sensitive: false, language: "", }; diff --git a/packages/megalodon/src/misskey.ts b/packages/megalodon/src/misskey.ts index f2befd31e3..2c0b140bfb 100644 --- a/packages/megalodon/src/misskey.ts +++ b/packages/megalodon/src/misskey.ts @@ -1529,6 +1529,23 @@ export default class Misskey implements MegalodonInterface { .then(res => res.data[0] ?? '⭐'); } + private async getDefaultPostPrivacy(): Promise { + // NOTE: get-unsecure is calckey's extension. + // Misskey doesn't have this endpoint and regular `/i/registry/get` won't work + // unless you have a 'nativeToken', which is reserved for the frontend webapp. + + return this.client + .post('/api/i/registry/get-unsecure', { + key: 'defaultNoteVisibility', + scope: ['client', 'base'], + }) + .then(res => { + if (!res.data || (res.data != 'public' && res.data != 'home' && res.data != 'followers' && res.data != 'specified')) + return 'public'; + return this.converter.visibility(res.data); + }); + } + public async unfavouriteStatus(id: string): Promise> { // NOTE: Misskey allows only one reaction per status, so we don't need to care what that emoji was. return this.deleteEmojiReaction(id, ''); From 2446822680a59bfabe8b6003dcdef6a5023396d8 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sat, 8 Jul 2023 21:52:55 +0200 Subject: [PATCH 21/36] [mastodon-client] send proper user preferences --- packages/megalodon/src/misskey.ts | 24 +++++--------------- packages/megalodon/src/misskey/api_client.ts | 4 ++-- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/packages/megalodon/src/misskey.ts b/packages/megalodon/src/misskey.ts index 2c0b140bfb..c3bbfb746f 100644 --- a/packages/megalodon/src/misskey.ts +++ b/packages/megalodon/src/misskey.ts @@ -1079,23 +1079,11 @@ export default class Misskey implements MegalodonInterface { // accounts/preferences // ====================================== public async getPreferences(): Promise> { - return this.client.post('/api/i').then(res => { - /* - return this.client.post('/api/i/registry/get-all', { - scope: ['client', 'base'], - }).then(ga => { - return Object.assign(res, { - data: this.converter.userPreferences(res.data, ga.data) - }) - }) - */ - - // TODO: - // FIXME: get this from api - return Object.assign(res, { - data: this.converter.userPreferences(res.data, {defaultNoteVisibility: "followers", tutorial: -1}) - }) - }) + return this.client.post('/api/i').then(async res => { + return Object.assign(res, { + data: this.converter.userPreferences(res.data, await this.getDefaultPostPrivacy()) + }) + }) } // ====================================== @@ -1529,7 +1517,7 @@ export default class Misskey implements MegalodonInterface { .then(res => res.data[0] ?? '⭐'); } - private async getDefaultPostPrivacy(): Promise { + private async getDefaultPostPrivacy(): Promise<'public' | 'unlisted' | 'private' | 'direct'> { // NOTE: get-unsecure is calckey's extension. // Misskey doesn't have this endpoint and regular `/i/registry/get` won't work // unless you have a 'nativeToken', which is reserved for the frontend webapp. diff --git a/packages/megalodon/src/misskey/api_client.ts b/packages/megalodon/src/misskey/api_client.ts index 7f1409c706..dec98fc225 100644 --- a/packages/megalodon/src/misskey/api_client.ts +++ b/packages/megalodon/src/misskey/api_client.ts @@ -174,13 +174,13 @@ namespace MisskeyAPI { } } - userPreferences = (u: MisskeyAPI.Entity.UserDetailMe, g: MisskeyAPI.Entity.GetAll): MegalodonEntity.Preferences => { + userPreferences = (u: MisskeyAPI.Entity.UserDetailMe, v: 'public' | 'unlisted' | 'private' | 'direct'): MegalodonEntity.Preferences => { return { "reading:expand:media": "default", "reading:expand:spoilers": false, "posting:default:language": u.lang, "posting:default:sensitive": u.alwaysMarkNsfw, - "posting:default:visibility": this.visibility(g.defaultNoteVisibility) + "posting:default:visibility": v } } From 12d7246bf3917d5b79a293ea02ba184f0c03cd9b Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sat, 8 Jul 2023 23:35:27 +0200 Subject: [PATCH 22/36] [mastodon-client] media caption support --- packages/backend/src/server/api/index.ts | 2 +- packages/megalodon/src/misskey.ts | 29 ++++++++++++++++++------ 2 files changed, 23 insertions(+), 8 deletions(-) diff --git a/packages/backend/src/server/api/index.ts b/packages/backend/src/server/api/index.ts index 29cfbf93c0..9e8c458868 100644 --- a/packages/backend/src/server/api/index.ts +++ b/packages/backend/src/server/api/index.ts @@ -112,7 +112,7 @@ mastoFileRouter.post("/v2/media", upload.single("file"), async (ctx) => { ctx.status = 401; return; } - const data = await client.uploadMedia(multipartData); + const data = await client.uploadMedia(multipartData, ctx.request.body); ctx.body = convertAttachment(data.data as Entity.Attachment); } catch (e: any) { console.error(e); diff --git a/packages/megalodon/src/misskey.ts b/packages/megalodon/src/misskey.ts index c3bbfb746f..97b17a0d61 100644 --- a/packages/megalodon/src/misskey.ts +++ b/packages/megalodon/src/misskey.ts @@ -1643,20 +1643,29 @@ export default class Misskey implements MegalodonInterface { /** * POST /api/drive/files/create */ - public async uploadMedia(file: any, _options?: { description?: string; focus?: string }): Promise> { + public async uploadMedia(file: any, options?: { description?: string; focus?: string }): Promise> { const formData = new FormData() - formData.append('file', fs.createReadStream(file.path), { - contentType: file.mimetype, - filename: file.originalname, - }) + formData.append('file', fs.createReadStream(file.path), { + contentType: file.mimetype, + filename: file.originalname + }) + + if (file.originalname != null) { + formData.append('name', file.originalname); + } + + if (options?.description != null) { + formData.append('comment', options.description); + } + let headers: { [key: string]: string } = {} if (typeof formData.getHeaders === 'function') { headers = formData.getHeaders() } return this.client .post('/api/drive/files/create', formData, headers) - .then(res => ({ ...res, data: this.converter.file(res.data) })) - } + .then(res => ({ ...res, data: this.converter.file(res.data) })) + } public async getMedia(id: string): Promise> { const res = await this.client.post('/api/drive/files/show', { fileId: id }) @@ -1684,6 +1693,12 @@ export default class Misskey implements MegalodonInterface { isSensitive: options.is_sensitive }) } + + if (options.description !== undefined) { + params = Object.assign(params, { + comment: options.description + }) + } } return this.client .post('/api/drive/files/update', params) From 69d1c9746ab7ccb1dc54fe1ca891acfc71b61547 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sat, 8 Jul 2023 23:50:25 +0200 Subject: [PATCH 23/36] [mastodon-client] drive file name fixup --- packages/megalodon/src/misskey.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/packages/megalodon/src/misskey.ts b/packages/megalodon/src/misskey.ts index 97b17a0d61..39665572c9 100644 --- a/packages/megalodon/src/misskey.ts +++ b/packages/megalodon/src/misskey.ts @@ -1646,17 +1646,14 @@ export default class Misskey implements MegalodonInterface { public async uploadMedia(file: any, options?: { description?: string; focus?: string }): Promise> { const formData = new FormData() formData.append('file', fs.createReadStream(file.path), { - contentType: file.mimetype, - filename: file.originalname + contentType: file.mimetype }) - if (file.originalname != null) { + if (file.originalname != null && file.originalname !== 'file') formData.append('name', file.originalname); - } - if (options?.description != null) { + if (options?.description != null) formData.append('comment', options.description); - } let headers: { [key: string]: string } = {} if (typeof formData.getHeaders === 'function') { From a9ae14431dd438850460daca2d282b933de1b306 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sun, 9 Jul 2023 00:14:03 +0200 Subject: [PATCH 24/36] [mastodon-client] TODO/FIXME cleanup --- packages/megalodon/src/misskey/api_client.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/megalodon/src/misskey/api_client.ts b/packages/megalodon/src/misskey/api_client.ts index dec98fc225..34e11784e0 100644 --- a/packages/megalodon/src/misskey/api_client.ts +++ b/packages/megalodon/src/misskey/api_client.ts @@ -134,8 +134,8 @@ namespace MisskeyAPI { url: acctUrl, avatar: u.avatarUrl, avatar_static: u.avatarUrl, - header: this.plcUrl, // FIXME - header_static: this.plcUrl, // FIXME + header: this.plcUrl, + header_static: this.plcUrl, emojis: u.emojis.map(e => this.emoji(e)), moved: null, fields: [], @@ -308,7 +308,7 @@ namespace MisskeyAPI { emojis: n.emojis.map(e => this.emoji(e)), replies_count: n.repliesCount, reblogs_count: n.renoteCount, - favourites_count: this.getTotalReactions(n.reactions), // FIXME: instead get # of default reaction emoji reactions + favourites_count: this.getTotalReactions(n.reactions), reblogged: false, favourited: !!n.myReaction, muted: false, From e47e905ce9196d14e3126ab08b69b29524e091c4 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sun, 9 Jul 2023 00:20:14 +0200 Subject: [PATCH 25/36] [mastodon-client] enforce limits for /following and /followers --- packages/megalodon/src/misskey.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/megalodon/src/misskey.ts b/packages/megalodon/src/misskey.ts index 39665572c9..7e9bc6c8a9 100644 --- a/packages/megalodon/src/misskey.ts +++ b/packages/megalodon/src/misskey.ts @@ -460,7 +460,7 @@ export default class Misskey implements MegalodonInterface { if (options) { if (options.limit) { params = Object.assign(params, { - limit: options.limit + limit: options.limit <= 100 ? options.limit : 100 }) } else { @@ -498,7 +498,7 @@ export default class Misskey implements MegalodonInterface { if (options) { if (options.limit) { params = Object.assign(params, { - limit: options.limit + limit: options.limit <= 100 ? options.limit : 100 }) } } From 858549ce4193a527a2678ab26d02e5319298f63c Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sun, 9 Jul 2023 00:31:24 +0200 Subject: [PATCH 26/36] [mastodon-client] populate user details for account following/followers --- packages/megalodon/src/misskey.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/megalodon/src/misskey.ts b/packages/megalodon/src/misskey.ts index 7e9bc6c8a9..e05a12eaad 100644 --- a/packages/megalodon/src/misskey.ts +++ b/packages/megalodon/src/misskey.ts @@ -474,11 +474,11 @@ export default class Misskey implements MegalodonInterface { limit: 40 }) } - return this.client.post>('/api/users/followers', params).then(res => { - return Object.assign(res, { - data: res.data.map(f => this.converter.follower(f)) - }) - }) + return this.client.post>('/api/users/followers', params).then(async res => { + return Object.assign(res, { + data: (await Promise.all(res.data.map(async f => (this.getAccount(f.followerId)).then(p => p.data)))) + }) + }) } /** @@ -502,11 +502,11 @@ export default class Misskey implements MegalodonInterface { }) } } - return this.client.post>('/api/users/following', params).then(res => { - return Object.assign(res, { - data: res.data.map(f => this.converter.following(f)) - }) - }) + return this.client.post>('/api/users/following', params).then(async res => { + return Object.assign(res, { + data: (await Promise.all(res.data.map(async f => (this.getAccount(f.followeeId)).then(p => p.data)))) + }) + }) } public async getAccountLists(_id: string): Promise>> { From 364266da0ae9b07d13ef0f3ff9a5f65baf94c8f4 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 8 Jul 2023 16:19:55 -0700 Subject: [PATCH 27/36] fix: :bug: server stats setting, meta fetching --- packages/backend/src/daemons/server-stats.ts | 6 ++++-- packages/client/src/pages/admin/settings.vue | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/backend/src/daemons/server-stats.ts b/packages/backend/src/daemons/server-stats.ts index ba74278762..42e19d813b 100644 --- a/packages/backend/src/daemons/server-stats.ts +++ b/packages/backend/src/daemons/server-stats.ts @@ -21,8 +21,10 @@ export default function () { ev.emit(`serverStatsLog:${x.id}`, log.slice(0, x.length || 50)); }); - const meta = fetchMeta(); - if (!meta.enableServerMachineStats) return; + fetchMeta().then((meta) => { + if (!meta.enableServerMachineStats) return; + } + ); async function tick() { const cpu = await cpuUsage(); diff --git a/packages/client/src/pages/admin/settings.vue b/packages/client/src/pages/admin/settings.vue index 5108c06965..b03a98ae54 100644 --- a/packages/client/src/pages/admin/settings.vue +++ b/packages/client/src/pages/admin/settings.vue @@ -468,6 +468,7 @@ let enableIdenticonGeneration: boolean = $ref(false); async function init() { const meta = await os.api("admin/meta"); + if (!meta) throw new Error("No meta"); name = meta.name; description = meta.description; tosUrl = meta.tosUrl; From 45de86370fcc605b4c66d8d2236878d4e969d4c4 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 8 Jul 2023 16:21:15 -0700 Subject: [PATCH 28/36] chore: :art: format --- packages/backend/src/daemons/server-stats.ts | 3 +-- packages/client/src/pages/user/home.vue | 7 ++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/daemons/server-stats.ts b/packages/backend/src/daemons/server-stats.ts index 42e19d813b..7d4fcd25e1 100644 --- a/packages/backend/src/daemons/server-stats.ts +++ b/packages/backend/src/daemons/server-stats.ts @@ -23,8 +23,7 @@ export default function () { fetchMeta().then((meta) => { if (!meta.enableServerMachineStats) return; - } - ); + }); async function tick() { const cpu = await cpuUsage(); diff --git a/packages/client/src/pages/user/home.vue b/packages/client/src/pages/user/home.vue index 54e4ab10c8..bef90dd7d7 100644 --- a/packages/client/src/pages/user/home.vue +++ b/packages/client/src/pages/user/home.vue @@ -26,7 +26,12 @@ class="banner" :style="{ backgroundImage: `url('${user.bannerUrl}')`, - '--backgroundImageStatic': defaultStore.state.useBlurEffect ? `url('${getStaticImageUrl(user.bannerUrl)}')` : null + '--backgroundImageStatic': defaultStore + .state.useBlurEffect + ? `url('${getStaticImageUrl( + user.bannerUrl, + )}')` + : null, }" >
From 83bcd4fe5627aa4aae33775608d4b1ad4ac62b95 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 8 Jul 2023 17:21:32 -0700 Subject: [PATCH 29/36] fix: :lipstick: url preview title size --- packages/client/src/components/MkUrlPreview.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/client/src/components/MkUrlPreview.vue b/packages/client/src/components/MkUrlPreview.vue index c217909f98..26cc7f24d2 100644 --- a/packages/client/src/components/MkUrlPreview.vue +++ b/packages/client/src/components/MkUrlPreview.vue @@ -51,7 +51,7 @@
-

{{ title || url }}

+

{{ title || url }}

From 9ecffcb1f94d51cebec10d13e7ba51f4106a2266 Mon Sep 17 00:00:00 2001 From: freeplay Date: Sat, 8 Jul 2023 20:30:24 -0400 Subject: [PATCH 30/36] style; proper styling for url preview --- packages/client/src/components/MkUrlPreview.vue | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/client/src/components/MkUrlPreview.vue b/packages/client/src/components/MkUrlPreview.vue index 26cc7f24d2..6452e135da 100644 --- a/packages/client/src/components/MkUrlPreview.vue +++ b/packages/client/src/components/MkUrlPreview.vue @@ -51,7 +51,7 @@

-

{{ title || url }}

+

{{ title || url }}

@@ -240,7 +240,7 @@ onUnmounted(() => { width: 0; flex-grow: 1; } - h1, + h3, p { display: block; margin: 0; @@ -248,7 +248,7 @@ onUnmounted(() => { text-overflow: ellipsis; max-width: 100%; } - h1 { + h3 { font-size: 1em; white-space: nowrap; margin-bottom: 0.2em; From 19470265f39ef3a8d8ee5bcfbe41745cf982fe46 Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sun, 9 Jul 2023 03:17:41 +0200 Subject: [PATCH 31/36] [mastodon-client] always sort timelines by id (descending) --- packages/megalodon/src/misskey.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/packages/megalodon/src/misskey.ts b/packages/megalodon/src/misskey.ts index e05a12eaad..981be7fb30 100644 --- a/packages/megalodon/src/misskey.ts +++ b/packages/megalodon/src/misskey.ts @@ -1841,7 +1841,7 @@ export default class Misskey implements MegalodonInterface { .post>('/api/notes/global-timeline', params) .then(async res => ({ ...res, - data: await Promise.all(res.data.map(n => this.noteWithDetails(n, this.baseUrlToHost(this.baseUrl), accountCache))) + data: (await Promise.all(res.data.map(n => this.noteWithDetails(n, this.baseUrlToHost(this.baseUrl), accountCache)))).sort(this.sortByIdDesc) })) } @@ -1899,7 +1899,7 @@ export default class Misskey implements MegalodonInterface { .post>('/api/notes/local-timeline', params) .then(async res => ({ ...res, - data: await Promise.all(res.data.map(n => this.noteWithDetails(n, this.baseUrlToHost(this.baseUrl), accountCache))) + data: (await Promise.all(res.data.map(n => this.noteWithDetails(n, this.baseUrlToHost(this.baseUrl), accountCache)))).sort(this.sortByIdDesc) })) } @@ -1963,7 +1963,7 @@ export default class Misskey implements MegalodonInterface { .post>('/api/notes/search-by-tag', params) .then(async res => ({ ...res, - data: await Promise.all(res.data.map(n => this.noteWithDetails(n, this.baseUrlToHost(this.baseUrl), accountCache))) + data: (await Promise.all(res.data.map(n => this.noteWithDetails(n, this.baseUrlToHost(this.baseUrl), accountCache)))).sort(this.sortByIdDesc) })) } @@ -2018,7 +2018,7 @@ export default class Misskey implements MegalodonInterface { .post>('/api/notes/timeline', params) .then(async res => ({ ...res, - data: await Promise.all(res.data.map(n => this.noteWithDetails(n, this.baseUrlToHost(this.baseUrl), accountCache))) + data: (await Promise.all(res.data.map(n => this.noteWithDetails(n, this.baseUrlToHost(this.baseUrl), accountCache)))).sort(this.sortByIdDesc) })) } @@ -2074,7 +2074,7 @@ export default class Misskey implements MegalodonInterface { } return this.client .post>('/api/notes/user-list-timeline', params) - .then(async res => ({ ...res, data: await Promise.all(res.data.map(n => this.noteWithDetails(n, this.baseUrlToHost(this.baseUrl), accountCache))) })) + .then(async res => ({ ...res, data: (await Promise.all(res.data.map(n => this.noteWithDetails(n, this.baseUrlToHost(this.baseUrl), accountCache)))).sort(this.sortByIdDesc) })) } // ====================================== @@ -2144,6 +2144,15 @@ export default class Misskey implements MegalodonInterface { }) } + private sortByIdDesc(a: Entity.Status, b: Entity.Status): number { + if (a.id < b.id) + return 1; + if (a.id > b.id) + return -1; + + return 0; + } + // ====================================== // timelines/lists // ====================================== From bd1faa9ab3e6fa02b6df6c7dc30d481a94de821c Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Sun, 9 Jul 2023 03:44:41 +0200 Subject: [PATCH 32/36] [mastodon-client] enforce limit for notifications --- packages/megalodon/src/misskey.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/megalodon/src/misskey.ts b/packages/megalodon/src/misskey.ts index 981be7fb30..dbf3471c0f 100644 --- a/packages/megalodon/src/misskey.ts +++ b/packages/megalodon/src/misskey.ts @@ -2285,7 +2285,7 @@ export default class Misskey implements MegalodonInterface { if (options) { if (options.limit) { params = Object.assign(params, { - limit: options.limit + limit: options.limit <= 100 ? options.limit : 100 }) } else { From a19e014cc56fd2f2eb3970061eac2248a1b20044 Mon Sep 17 00:00:00 2001 From: freeplay Date: Sat, 8 Jul 2023 23:21:02 -0400 Subject: [PATCH 33/36] fix: MkMedia #10429 ? + styling --- packages/client/src/components/MkMedia.vue | 50 +++++++++++++++------- 1 file changed, 34 insertions(+), 16 deletions(-) diff --git a/packages/client/src/components/MkMedia.vue b/packages/client/src/components/MkMedia.vue index 05965a4754..d697054b6a 100644 --- a/packages/client/src/components/MkMedia.vue +++ b/packages/client/src/components/MkMedia.vue @@ -1,5 +1,5 @@