From 44bf99e0c1427a56058fbb56f5fba7e826ec2df2 Mon Sep 17 00:00:00 2001 From: Namekuji Date: Fri, 30 Jun 2023 17:44:36 -0400 Subject: [PATCH 01/36] fix: multiple boost publication by relay --- packages/backend/src/services/note/create.ts | 98 ++++++++++---------- 1 file changed, 51 insertions(+), 47 deletions(-) diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index defd9742e2..2a5845943e 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -461,57 +461,61 @@ export default async ( } if (!dontFederateInitially) { - const relays = await getCachedRelays(); - // Some relays (e.g., aode-relay) deliver posts by boosting them as - // Announce activities. In that case, user is the relay's actor. - const boostedByRelay = - !!user.inbox && - relays.map((relay) => relay.inbox).includes(user.inbox); - - if (!note.uri) { + if (!note.userHost) { // Publish if the post is local publishNotesStream(note); - } else if (boostedByRelay && data.renote?.uri) { - // Use Redis transaction for atomicity - await redisClient.watch(`publishedNote:${data.renote.uri}`); - const exists = await redisClient.exists( - `publishedNote:${data.renote.uri}`, - ); - if (exists === 0) { - // Start the transaction - const transaction = redisClient.multi(); - const key = `publishedNote:${data.renote.uri}`; - transaction.set(key, 1, "EX", 30); - // Execute the transaction - transaction.exec((err, replies) => { - // Publish after setting the key in Redis - if (!err && data.renote) { - publishNotesStream(data.renote); - } - }); + } else { + const relays = await getCachedRelays(); + // Some relays (e.g., aode-relay) deliver posts by boosting them as + // Announce activities. In that case, user is the relay's actor. + const boostedByRelay = relays + .map((relay) => new URL(relay.inbox).host) + .includes(note.userHost); + + if (boostedByRelay && data.renote) { + // Use Redis transaction for atomicity + const key = `publishedNote:${data.renote.id}`; + await redisClient.watch(key); + const exists = await redisClient.exists(key); + if (exists === 0) { + // Start the transaction + const transaction = redisClient.multi(); + transaction.set(key, 1, "EX", 30); + // Execute the transaction + await transaction.exec((err, _replies) => { + // Publish after setting the key in Redis + if (!err && boostedByRelay && data.renote) { + publishNotesStream(data.renote); + } + }); + } else { + // Abort the transaction + redisClient.unwatch(); + } } else { - // Abort the transaction - redisClient.unwatch(); - } - } else if (!boostedByRelay && note.uri) { - // Use Redis transaction for atomicity - await redisClient.watch(`publishedNote:${note.uri}`); - const exists = await redisClient.exists(`publishedNote:${note.uri}`); - if (exists === 0) { - // Start the transaction - const transaction = redisClient.multi(); - const key = `publishedNote:${note.uri}`; - transaction.set(key, 1, "EX", 30); - // Execute the transaction - transaction.exec((err, replies) => { - // Publish after setting the key in Redis - if (!err) { - publishNotesStream(note); + // Use Redis transaction for atomicity + const key = `publishedNote:${note.id}`; + await redisClient.watch(key); + const exists = await redisClient.exists(key); + if (exists === 0) { + // Start the transaction + const transaction = redisClient.multi(); + transaction.set(key, 1, "EX", 30); + if (note.renoteId) { + // Prevent other threads from publishing this boosting post + transaction.set(`publishedNote:${note.renoteId}`, 1, "EX", 30); } - }); - } else { - // Abort the transaction - redisClient.unwatch(); + // Execute the transaction + await transaction.exec((err, _replies) => { + // Publish after setting the key in Redis + if (!err) { + publishNotesStream(note); + } + }); + } else { + // Abort the transaction + redisClient.unwatch(); + } } } } From 159f788696ef81352ab5a083f5becc36f2d605f7 Mon Sep 17 00:00:00 2001 From: Namekuji Date: Fri, 30 Jun 2023 18:13:07 -0400 Subject: [PATCH 02/36] fix: ignore if post boosted by relay is local --- packages/backend/src/services/note/create.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 2a5845943e..dd08aca41d 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -472,7 +472,8 @@ export default async ( .map((relay) => new URL(relay.inbox).host) .includes(note.userHost); - if (boostedByRelay && data.renote) { + if (boostedByRelay && data.renote && data.renote.userHost) { + /* A relay boosted a remote post. */ // Use Redis transaction for atomicity const key = `publishedNote:${data.renote.id}`; await redisClient.watch(key); From f53fa96fc6d4c34ffdf2d58fad3efd862647d1d7 Mon Sep 17 00:00:00 2001 From: Namekuji Date: Fri, 30 Jun 2023 18:35:05 -0400 Subject: [PATCH 03/36] refactor: no url instantiation --- packages/backend/src/services/note/create.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index dd08aca41d..369b3e4f77 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -461,16 +461,16 @@ export default async ( } if (!dontFederateInitially) { - if (!note.userHost) { + if (Users.isLocalUser(user)) { // Publish if the post is local publishNotesStream(note); } else { const relays = await getCachedRelays(); // Some relays (e.g., aode-relay) deliver posts by boosting them as // Announce activities. In that case, user is the relay's actor. - const boostedByRelay = relays - .map((relay) => new URL(relay.inbox).host) - .includes(note.userHost); + const boostedByRelay = + !!user.inbox && + relays.map((relay) => relay.inbox).includes(user.inbox); if (boostedByRelay && data.renote && data.renote.userHost) { /* A relay boosted a remote post. */ From 38d4d347135d37ef873b43b9e7227e7963d0bc59 Mon Sep 17 00:00:00 2001 From: Namekuji Date: Sat, 1 Jul 2023 00:50:46 -0400 Subject: [PATCH 04/36] refactor: use redis-semaphore for mutex across workers --- packages/backend/package.json | 1 + packages/backend/src/services/note/create.ts | 89 ++++++++------------ pnpm-lock.yaml | 17 ++++ 3 files changed, 53 insertions(+), 54 deletions(-) diff --git a/packages/backend/package.json b/packages/backend/package.json index f7d19d85b2..b584a56910 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -112,6 +112,7 @@ "ratelimiter": "3.4.1", "re2": "1.19.0", "redis-lock": "0.1.4", + "redis-semaphore": "5.3.1", "reflect-metadata": "0.1.13", "rename": "1.0.4", "rndstr": "1.0.0", diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 369b3e4f77..6d64bec50e 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -69,6 +69,7 @@ import { getActiveWebhooks } from "@/misc/webhook-cache.js"; import { shouldSilenceInstance } from "@/misc/should-block-instance.js"; import meilisearch from "../../db/meilisearch.js"; import { redisClient } from "@/db/redis.js"; +import { Mutex } from "redis-semaphore"; const mutedWordsCache = new Cache< { userId: UserProfile["userId"]; mutedWords: UserProfile["mutedWords"] }[] @@ -461,63 +462,43 @@ export default async ( } if (!dontFederateInitially) { - if (Users.isLocalUser(user)) { - // Publish if the post is local - publishNotesStream(note); - } else { - const relays = await getCachedRelays(); - // Some relays (e.g., aode-relay) deliver posts by boosting them as - // Announce activities. In that case, user is the relay's actor. - const boostedByRelay = - !!user.inbox && - relays.map((relay) => relay.inbox).includes(user.inbox); + let publishKey: string; + let noteToPublish: Note; + const relays = await getCachedRelays(); - if (boostedByRelay && data.renote && data.renote.userHost) { - /* A relay boosted a remote post. */ - // Use Redis transaction for atomicity - const key = `publishedNote:${data.renote.id}`; - await redisClient.watch(key); - const exists = await redisClient.exists(key); - if (exists === 0) { - // Start the transaction - const transaction = redisClient.multi(); - transaction.set(key, 1, "EX", 30); - // Execute the transaction - await transaction.exec((err, _replies) => { - // Publish after setting the key in Redis - if (!err && boostedByRelay && data.renote) { - publishNotesStream(data.renote); - } - }); - } else { - // Abort the transaction - redisClient.unwatch(); - } - } else { - // Use Redis transaction for atomicity - const key = `publishedNote:${note.id}`; - await redisClient.watch(key); - const exists = await redisClient.exists(key); - if (exists === 0) { - // Start the transaction - const transaction = redisClient.multi(); - transaction.set(key, 1, "EX", 30); - if (note.renoteId) { - // Prevent other threads from publishing this boosting post - transaction.set(`publishedNote:${note.renoteId}`, 1, "EX", 30); - } - // Execute the transaction - await transaction.exec((err, _replies) => { - // Publish after setting the key in Redis - if (!err) { - publishNotesStream(note); - } - }); - } else { - // Abort the transaction - redisClient.unwatch(); + // Some relays (e.g., aode-relay) deliver posts by boosting them as + // Announce activities. In that case, user is the relay's actor. + const boostedByRelay = + !!user.inbox && + relays.map((relay) => relay.inbox).includes(user.inbox); + + if (boostedByRelay && data.renote && data.renote.userHost) { + publishKey = `publishedNote:${data.renote.id}`; + noteToPublish = data.renote; + } else { + publishKey = `publishedNote:${note.id}`; + noteToPublish = note; + } + + const lock = new Mutex(redisClient, "publishedNote:lock"); + await lock.acquire(); + try { + const exists = (await redisClient.exists(publishKey)) > 0; + if (!exists) { + await redisClient.set(publishKey, 1, "EX", 30); + if (noteToPublish.renoteId) { + // Prevents other threads from publishing the boosting post + await redisClient.set( + `publishedNote:${noteToPublish.renoteId}`, + 1, + "EX", + 30, + ); } + publishNotesStream(noteToPublish); } + } finally { + lock.release(); } } if (note.replyId != null) { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 760931858b..1002a6f958 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -339,6 +339,9 @@ importers: redis-lock: specifier: 0.1.4 version: 0.1.4 + redis-semaphore: + specifier: 5.3.1 + version: 5.3.1(ioredis@5.3.2) reflect-metadata: specifier: 0.1.13 version: 0.1.13 @@ -2666,6 +2669,7 @@ packages: engines: {node: '>=10'} cpu: [arm64] os: [android] + requiresBuild: true dependencies: '@swc/wasm': 1.2.130 @@ -2772,6 +2776,7 @@ packages: /@swc/wasm@1.2.130: resolution: {integrity: sha512-rNcJsBxS70+pv8YUWwf5fRlWX6JoY/HJc25HD/F8m6Kv7XhJdqPPMhyX6TKkUBPAG7TWlZYoxa+rHAjPy4Cj3Q==} + requiresBuild: true /@syuilo/aiscript@0.11.1: resolution: {integrity: sha512-chwOIA3yLUKvOB0G611hjLArKTeOWNmTm3lHERSaDW1d+dS6do56naX6Lkwy2UpnwWC0qzeNSgg35elk6t2gZg==} @@ -12831,6 +12836,18 @@ packages: dependencies: redis-errors: 1.2.0 + /redis-semaphore@5.3.1(ioredis@5.3.2): + resolution: {integrity: sha512-oUpxxfxSbh5eT0mvVpz2d4Qlg2CsaoQkeo80/v6CU2l97zO0u6NPgc9/zQZa9KGR3/93b0igtSct3hEFh8Ei8w==} + engines: {node: '>= 14.17.0'} + peerDependencies: + ioredis: ^4.1.0 || ^5 + dependencies: + debug: 4.3.4(supports-color@8.1.1) + ioredis: 5.3.2 + transitivePeerDependencies: + - supports-color + dev: false + /redis@4.6.7: resolution: {integrity: sha512-KrkuNJNpCwRm5vFJh0tteMxW8SaUzkm5fBH7eL5hd/D0fAkzvapxbfGPP/r+4JAXdQuX7nebsBkBqA2RHB7Usw==} dependencies: From 4bf1dbbd83333b7058a8eb77f64bbc725f266fd3 Mon Sep 17 00:00:00 2001 From: Namekuji Date: Sat, 1 Jul 2023 02:53:08 -0400 Subject: [PATCH 05/36] change mutex key --- packages/backend/src/services/note/create.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 6d64bec50e..95d005fe00 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -480,7 +480,7 @@ export default async ( noteToPublish = note; } - const lock = new Mutex(redisClient, "publishedNote:lock"); + const lock = new Mutex(redisClient, "publishedNote"); await lock.acquire(); try { const exists = (await redisClient.exists(publishKey)) > 0; From ab789f2ca8c95c2e7fb8d978a25e6f671804e07d Mon Sep 17 00:00:00 2001 From: Namekuji Date: Sat, 1 Jul 2023 03:22:40 -0400 Subject: [PATCH 06/36] fix: await release --- packages/backend/src/services/note/create.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 95d005fe00..6eb0df8170 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -498,7 +498,7 @@ export default async ( publishNotesStream(noteToPublish); } } finally { - lock.release(); + await lock.release(); } } if (note.replyId != null) { From 49e17e776c2276ee7f87ca4d59fe8386060d7c64 Mon Sep 17 00:00:00 2001 From: Namekuji Date: Sat, 1 Jul 2023 04:07:50 -0400 Subject: [PATCH 07/36] refactor: examine by get instead of exists --- packages/backend/src/services/note/create.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/backend/src/services/note/create.ts b/packages/backend/src/services/note/create.ts index 6eb0df8170..f00678ce22 100644 --- a/packages/backend/src/services/note/create.ts +++ b/packages/backend/src/services/note/create.ts @@ -483,14 +483,14 @@ export default async ( const lock = new Mutex(redisClient, "publishedNote"); await lock.acquire(); try { - const exists = (await redisClient.exists(publishKey)) > 0; - if (!exists) { - await redisClient.set(publishKey, 1, "EX", 30); + const published = (await redisClient.get(publishKey)) !== null; + if (!published) { + await redisClient.set(publishKey, "done", "EX", 30); if (noteToPublish.renoteId) { // Prevents other threads from publishing the boosting post await redisClient.set( `publishedNote:${noteToPublish.renoteId}`, - 1, + "done", "EX", 30, ); From fc8f9f63ca98617d26f4f4d90dc29fecbc407a9b Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 1 Jul 2023 19:14:14 -0700 Subject: [PATCH 08/36] chore: :busts_in_silhouette: patrons --- patrons.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/patrons.json b/patrons.json index 7d38e5f005..d53643484a 100644 --- a/patrons.json +++ b/patrons.json @@ -10,8 +10,7 @@ "@griff@stop.voring.me", "@cafkafk@ck.cafkafk.com", "@privateger@plasmatrap.com", - "@self@neo.voidworks.cc", - "@effy@social.effy.space", + "@effye@toot.thoughtworks.com", "@Kio@kitsunes.club", "@twann@tech.lgbt", "@surfbum@calckey.nz", @@ -35,13 +34,12 @@ "@box464@calckey.social", "@MariaTheMartian@calckey.social", "@nisemikol@calckey.social", - "@smallpatatas@calckey.patatas.ca", + "@smallpatatas@blahaj.zone", "@bayra@stop.voring.me", "@frost@wolfdo.gg", "@joebiden@fuckgov.org", "@nyaa@calckey.social", "@Dan@calckey.social", - "@testing@stop.voring.me", "@dana@calckey.social", "@Jdreben@calckey.social", "@natalie@prismst.one", @@ -77,6 +75,7 @@ "@jtbennett@noc.social", "@renere@distance.blue", "@theking@kitsunes.club", + "@toof@fedi.toofie.net", "\nInterkosmos Link" ] } From 1048c1f6762f3cdc2753f354c8796fb360631778 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 1 Jul 2023 19:17:22 -0700 Subject: [PATCH 09/36] chore: :busts_in_silhouette: patrons --- patrons.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/patrons.json b/patrons.json index d53643484a..41c53f9851 100644 --- a/patrons.json +++ b/patrons.json @@ -17,9 +17,8 @@ "@topher@mastodon.online", "@hanicef@stop.voring.me", "@nmkj@calckey.jp", - "@trapezial@calckey.jp", "@unattributed@calckey.social", - "@cody@mk.codingneko.com", + "@cody@misskey.codingneko.com", "@kate@blahaj.zone", "@emtk@mkkey.net", "@jovikowi@calckey.social", From f2bedbd645f98edd72fc27dea5d6079f142b2238 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 1 Jul 2023 19:31:05 -0700 Subject: [PATCH 10/36] refactor: :globe_with_meridians: patrons description --- locales/en-US.yml | 1 + packages/client/src/pages/about-calckey.vue | 12 +++++++++--- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/locales/en-US.yml b/locales/en-US.yml index cc327c5aa5..5daff11a91 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -1213,6 +1213,7 @@ _aboutMisskey: morePatrons: "We also appreciate the support of many other helpers not listed here. Thank you! 🥰" patrons: "Calckey patrons" + patronsList: "Listed chronologically, not by donation size. Donate with the link above to get your name on here!" _nsfw: respect: "Hide NSFW media" ignore: "Don't hide NSFW media" diff --git a/packages/client/src/pages/about-calckey.vue b/packages/client/src/pages/about-calckey.vue index 6071a2c2d9..a8cee78d55 100644 --- a/packages/client/src/pages/about-calckey.vue +++ b/packages/client/src/pages/about-calckey.vue @@ -97,13 +97,16 @@ > - + + {{ i18n.ts._aboutMisskey.patrons }} +

+ {{ i18n.ts._aboutMisskey.patronsList }} +

Date: Sat, 1 Jul 2023 08:32:50 +0000 Subject: [PATCH 11/36] chore: Translated using Weblate (German) Currently translated at 98.7% (1793 of 1815 strings) Translation: Calckey/locales Translate-URL: https://hosted.weblate.org/projects/calckey/locales/de/ --- locales/de-DE.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/locales/de-DE.yml b/locales/de-DE.yml index d37869064d..de071e00e6 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -2152,3 +2152,4 @@ clipsDesc: Clips sind wie teilbare, kategorisierte Lesezeichen. Du kannst Clips Menü individueller Posts aus erstellen. channelFederationWarn: Kanäle föderieren noch nicht zu anderen Servern reactionPickerSkinTone: Bevorzugte Emoji-Hautfarbe +swipeOnMobile: Wischen zwischen den Seiten erlauben From d9af4f3a2737f32b054131aad4818e6659894e01 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 1 Jul 2023 20:00:51 -0700 Subject: [PATCH 12/36] refactor: :triangular_flag_on_post: post editing is no longer experimental --- locales/ca-ES.yml | 4 ---- locales/de-DE.yml | 3 --- locales/en-US.yml | 3 --- locales/fr-FR.yml | 2 +- locales/ja-JP.yml | 2 -- locales/zh-TW.yml | 1 - .../src/remote/activitypub/models/note.ts | 4 ---- .../src/server/api/endpoints/admin/meta.ts | 3 --- .../server/api/endpoints/admin/update-meta.ts | 1 - .../backend/src/server/api/endpoints/meta.ts | 2 +- .../src/server/api/endpoints/notes/edit.ts | 11 ----------- packages/backend/src/server/nodeinfo.ts | 2 +- packages/client/src/pages/admin/experiments.vue | 17 ----------------- packages/client/src/scripts/get-note-menu.ts | 2 +- 14 files changed, 4 insertions(+), 53 deletions(-) diff --git a/locales/ca-ES.yml b/locales/ca-ES.yml index 208ccb1598..e482750f4a 100644 --- a/locales/ca-ES.yml +++ b/locales/ca-ES.yml @@ -2082,11 +2082,7 @@ _experiments: alpha: Alfa beta: Beta release: Publicà - enablePostEditing: Activà l'edició de publicacions title: Experiments - postEditingCaption: Mostra l'opció perquè els usuaris editin les seves publicacions - mitjançant el menú d'opcions de publicació, i permet rebre publicacions editades - d'altres servidors. enablePostImports: Activar l'importació de publicacions postImportsCaption: Permet els usuaris importar publicacions desde comptes a Calckey, Misskey, Mastodon, Akkoma i Pleroma. Pot fer que el servidor vagi més lent durant diff --git a/locales/de-DE.yml b/locales/de-DE.yml index d37869064d..e9e33d6d65 100644 --- a/locales/de-DE.yml +++ b/locales/de-DE.yml @@ -2095,10 +2095,7 @@ jumpToPrevious: Zum Vorherigen springen silencedWarning: Diese Meldung wird angezeigt, weil diese Nutzer von Servern stammen, die Ihr Administrator abgeschaltet hat, so dass es sich möglicherweise um Spam handelt. _experiments: - enablePostEditing: Beitragsbearbeitung ermöglichen title: Funktionstests - postEditingCaption: Zeigt die Option für Nutzer an, ihre bestehenden Beiträge über - das Menü "Beitragsoptionen" zu bearbeiten enablePostImports: Beitragsimporte aktivieren postImportsCaption: Erlaubt es Nutzer:innen ihre Posts von alten Calckey, Misskey, Mastodon, Akkoma und Pleroma Accounts zu importieren. Bei Engpässen in der Warteschlange diff --git a/locales/en-US.yml b/locales/en-US.yml index 5daff11a91..d493f332f5 100644 --- a/locales/en-US.yml +++ b/locales/en-US.yml @@ -2070,9 +2070,6 @@ _deck: direct: "Direct messages" _experiments: title: "Experiments" - enablePostEditing: "Enable post editing" - postEditingCaption: "Shows the option for users to edit their existing posts via\ - \ the post options menu, and allows post edits from other instances to be recieved." enablePostImports: "Enable post imports" postImportsCaption: "Allows users to import their posts from past Calckey,\ \ Misskey, Mastodon, Akkoma, and Pleroma accounts. It may cause slowdowns during\ diff --git a/locales/fr-FR.yml b/locales/fr-FR.yml index 5a61870c4e..5291d16932 100644 --- a/locales/fr-FR.yml +++ b/locales/fr-FR.yml @@ -2028,7 +2028,7 @@ flagShowTimelineRepliesDescription: Si activé, affiche dans le fil les réponse _experiments: alpha: Alpha beta: Beta - enablePostEditing: Autoriser l'édition de note + enablePostImports: Autoriser l'importation de messages title: Expérimentations findOtherInstance: Trouver un autre serveur userSaysSomethingReasonQuote: '{name} a cité une note contenant {reason}' diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml index 21f616808b..fa3c3f1cc1 100644 --- a/locales/ja-JP.yml +++ b/locales/ja-JP.yml @@ -1887,9 +1887,7 @@ hiddenTagsDescription: 'トレンドと「みつける」から除外したい hiddenTags: 非表示にするハッシュタグ apps: "アプリ" _experiments: - enablePostEditing: 投稿の編集機能を有効にする title: 試験的な機能 - postEditingCaption: 投稿のメニューに既存の投稿を編集するボタンを表示し、他サーバーの編集も受信できるようにします。 postImportsCaption: ユーザーが過去の投稿をCalckey・Misskey・Mastodon・Akkoma・Pleromaからインポートすることを許可します。キューが溜まっているときにインポートするとサーバーに負荷がかかる可能性があります。 enablePostImports: 投稿のインポートを有効にする diff --git a/locales/zh-TW.yml b/locales/zh-TW.yml index d373daf5d9..c615bcdcc5 100644 --- a/locales/zh-TW.yml +++ b/locales/zh-TW.yml @@ -1816,7 +1816,6 @@ silenceThisInstance: 靜音此伺服器 silencedInstances: 已靜音的伺服器 silenced: 已靜音 _experiments: - enablePostEditing: 啟用帖子編輯 title: 試驗功能 findOtherInstance: 找找另一個伺服器 noGraze: 瀏覽器擴展 "Graze for Mastodon" 會與Calckey發生衝突,請停用該擴展。 diff --git a/packages/backend/src/remote/activitypub/models/note.ts b/packages/backend/src/remote/activitypub/models/note.ts index 26aa5bf544..a3141e388a 100644 --- a/packages/backend/src/remote/activitypub/models/note.ts +++ b/packages/backend/src/remote/activitypub/models/note.ts @@ -541,10 +541,6 @@ function notEmpty(partial: Partial) { export async function updateNote(value: string | IObject, resolver?: Resolver) { const uri = typeof value === "string" ? value : value.id; if (!uri) throw new Error("Missing note uri"); - const instanceMeta = await fetchMeta(); - if (instanceMeta.experimentalFeatures?.postEdits === false) { - throw new Error("Post edits disabled."); - } // Skip if URI points to this server if (uri.startsWith(`${config.url}/`)) throw new Error("uri points local"); diff --git a/packages/backend/src/server/api/endpoints/admin/meta.ts b/packages/backend/src/server/api/endpoints/admin/meta.ts index ad70310633..3193301275 100644 --- a/packages/backend/src/server/api/endpoints/admin/meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/meta.ts @@ -476,9 +476,6 @@ export const meta = { optional: true, nullable: true, properties: { - postEditing: { - type: "boolean", - }, postImports: { type: "boolean", }, diff --git a/packages/backend/src/server/api/endpoints/admin/update-meta.ts b/packages/backend/src/server/api/endpoints/admin/update-meta.ts index b967112a5c..cf22c6c489 100644 --- a/packages/backend/src/server/api/endpoints/admin/update-meta.ts +++ b/packages/backend/src/server/api/endpoints/admin/update-meta.ts @@ -174,7 +174,6 @@ export const paramDef = { type: "object", nullable: true, properties: { - postEditing: { type: "boolean" }, postImports: { type: "boolean" }, }, }, diff --git a/packages/backend/src/server/api/endpoints/meta.ts b/packages/backend/src/server/api/endpoints/meta.ts index f6c978b2de..673a0266c8 100644 --- a/packages/backend/src/server/api/endpoints/meta.ts +++ b/packages/backend/src/server/api/endpoints/meta.ts @@ -529,7 +529,7 @@ export default define(meta, paramDef, async (ps, me) => { github: instance.enableGithubIntegration, discord: instance.enableDiscordIntegration, serviceWorker: instance.enableServiceWorker, - postEditing: instance.experimentalFeatures?.postEditing || false, + postEditing: true, postImports: instance.experimentalFeatures?.postImports || false, miauth: true, }; diff --git a/packages/backend/src/server/api/endpoints/notes/edit.ts b/packages/backend/src/server/api/endpoints/notes/edit.ts index 14ce2faafc..70c5ceffb4 100644 --- a/packages/backend/src/server/api/endpoints/notes/edit.ts +++ b/packages/backend/src/server/api/endpoints/notes/edit.ts @@ -140,12 +140,6 @@ export const meta = { code: "NOT_LOCAL_USER", id: "b907f407-2aa0-4283-800b-a2c56290b822", }, - - editsDisabled: { - message: "Post edits are disabled.", - code: "EDITS_DISABLED", - id: "99306f00-fb81-11ed-be56-0242ac120002", - }, }, } as const; @@ -244,11 +238,6 @@ export const paramDef = { export default define(meta, paramDef, async (ps, user) => { if (user.movedToUri != null) throw new ApiError(meta.errors.accountLocked); - const instanceMeta = await fetchMeta(); - if (instanceMeta.experimentalFeatures?.postEdits === false) { - throw new ApiError(meta.errors.editsDisabled); - } - if (!Users.isLocalUser(user)) { throw new ApiError(meta.errors.notLocalUser); } diff --git a/packages/backend/src/server/nodeinfo.ts b/packages/backend/src/server/nodeinfo.ts index 18e04f4209..dbfb28ff6a 100644 --- a/packages/backend/src/server/nodeinfo.ts +++ b/packages/backend/src/server/nodeinfo.ts @@ -83,7 +83,7 @@ const nodeinfo2 = async () => { disableGlobalTimeline: meta.disableGlobalTimeline, emailRequiredForSignup: meta.emailRequiredForSignup, searchFilters: config.meilisearch ? true : false, - postEditing: meta.experimentalFeatures?.postEditing || false, + postEditing: true, postImports: meta.experimentalFeatures?.postImports || false, enableHcaptcha: meta.enableHcaptcha, enableRecaptcha: meta.enableRecaptcha, diff --git a/packages/client/src/pages/admin/experiments.vue b/packages/client/src/pages/admin/experiments.vue index 0c9a258cb4..32ce9bfae8 100644 --- a/packages/client/src/pages/admin/experiments.vue +++ b/packages/client/src/pages/admin/experiments.vue @@ -8,19 +8,6 @@ /> - - - - (null); type MetaExperiments = { experimentalFeatures?: { - postEditing?: boolean; postImports?: boolean; }; }; @@ -64,14 +49,12 @@ async function init() { meta = (await os.api("admin/meta")) as MetaExperiments; if (!meta) return; - enablePostEditing = meta.experimentalFeatures?.postEditing ?? false; enablePostImports = meta.experimentalFeatures?.postImports ?? false; } function save() { const experiments: MetaExperiments = { experimentalFeatures: { - postEditing: enablePostEditing, postImports: enablePostImports, }, }; diff --git a/packages/client/src/scripts/get-note-menu.ts b/packages/client/src/scripts/get-note-menu.ts index fa78c7ce54..75565a1ac3 100644 --- a/packages/client/src/scripts/get-note-menu.ts +++ b/packages/client/src/scripts/get-note-menu.ts @@ -408,7 +408,7 @@ export function getNoteMenu(props: { }, } : undefined, - instance.features.postEditing && isAppearAuthor + isAppearAuthor ? { icon: "ph-pencil-line ph-bold ph-lg", text: i18n.ts.edit, From cf3c3e823486c75277d258539a06bf6a7d25cac4 Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 1 Jul 2023 20:46:13 -0700 Subject: [PATCH 13/36] feat: :sparkles: celebrate on calendar when birthday --- packages/client/src/widgets/calendar.vue | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/packages/client/src/widgets/calendar.vue b/packages/client/src/widgets/calendar.vue index 655308d504..1377b44bf0 100644 --- a/packages/client/src/widgets/calendar.vue +++ b/packages/client/src/widgets/calendar.vue @@ -5,7 +5,7 @@ {{ i18n.t("yearX", { year }) }} {{ i18n.t("monthX", { month }) }}

-

+

🎉{{ i18n.t("dayX", { day }) }}🎉 { const now = new Date(); const nd = now.getDate(); @@ -121,6 +125,13 @@ const tick = () => { yearP.value = (yearNumer / yearDenom) * 100; isHoliday.value = now.getDay() === 0 || now.getDay() === 6; + + if (hasBirthday) { + const [bdayYear, bdayMonth, bdayDay] = $i.birthday.split("-"); + if (month.value === +bdayMonth && day.value == +bdayDay) { + isBirthday.value = true; + } + } }; useInterval(tick, 1000, { From 3d8fe32ef46f6ebf7205b86565e94ad6adaf1f8f Mon Sep 17 00:00:00 2001 From: ThatOneCalculator Date: Sat, 1 Jul 2023 20:46:33 -0700 Subject: [PATCH 14/36] =?UTF-8?q?chore:=20=F0=9F=8E=A8=20format?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/client/src/components/MkEmojiPickerDialog.vue | 5 ++--- packages/client/src/components/MkNotes.vue | 4 ++-- packages/client/src/components/MkTimeline.vue | 2 +- packages/client/src/pages/antenna-timeline.vue | 2 +- packages/client/src/pages/user/home.vue | 6 ++++-- packages/client/src/widgets/calendar.vue | 1 + 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/packages/client/src/components/MkEmojiPickerDialog.vue b/packages/client/src/components/MkEmojiPickerDialog.vue index 8bbb4bb850..204505e89f 100644 --- a/packages/client/src/components/MkEmojiPickerDialog.vue +++ b/packages/client/src/components/MkEmojiPickerDialog.vue @@ -67,9 +67,8 @@ function chosen(emoji: any) { function opening() { try { picker.value?.reset(); - } - catch (e) { - console.error(`Something's wrong with restting the emoji picker: ${e}`) + } catch (e) { + console.error(`Something's wrong with restting the emoji picker: ${e}`); } picker.value?.focus(); } diff --git a/packages/client/src/components/MkNotes.vue b/packages/client/src/components/MkNotes.vue index 3ddcb6079b..5916621840 100644 --- a/packages/client/src/components/MkNotes.vue +++ b/packages/client/src/components/MkNotes.vue @@ -53,12 +53,12 @@ const props = defineProps<{ const pagingComponent = ref>(); function scrollTop() { - scroll(tlEl.value, { top: 0, behavior: 'smooth' }) + scroll(tlEl.value, { top: 0, behavior: "smooth" }); } defineExpose({ pagingComponent, - scrollTop + scrollTop, }); diff --git a/packages/client/src/components/MkTimeline.vue b/packages/client/src/components/MkTimeline.vue index 81e4f575c6..8c57a29ef5 100644 --- a/packages/client/src/components/MkTimeline.vue +++ b/packages/client/src/components/MkTimeline.vue @@ -23,7 +23,7 @@ ref="tlComponent" :no-gap="!$store.state.showGapBetweenNotesInTimeline" :pagination="pagination" - @queue="(x) => queue = x" + @queue="(x) => (queue = x)" /> diff --git a/packages/client/src/pages/antenna-timeline.vue b/packages/client/src/pages/antenna-timeline.vue index fbee993d32..a99ba68724 100644 --- a/packages/client/src/pages/antenna-timeline.vue +++ b/packages/client/src/pages/antenna-timeline.vue @@ -126,7 +126,7 @@ definePageMetadata(