feat(koi): bumped sharkey + added no-xpost extension
This commit is contained in:
parent
a6a2482aac
commit
710fda269a
4 changed files with 250 additions and 7 deletions
|
@ -1,6 +1,6 @@
|
||||||
# based on https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/Dockerfile
|
# based on https://activitypub.software/TransFem-org/Sharkey/-/blob/develop/Dockerfile
|
||||||
ARG NODE_VERSION=20.12.2-alpine3.19
|
ARG NODE_VERSION=20.12.2-alpine3.19
|
||||||
ARG COMMIT=717696c4728d2e507ddfbd0e4890189758ab1087
|
ARG COMMIT=c344705d6708fdc725d6122d2b321cb2d01dad4b
|
||||||
|
|
||||||
FROM node:${NODE_VERSION} as build
|
FROM node:${NODE_VERSION} as build
|
||||||
|
|
||||||
|
@ -38,6 +38,7 @@ RUN git apply /patches/webhook-notification.patch
|
||||||
# motivation: https://very.stupid.fish/notes/9shhrn2qncid008s
|
# motivation: https://very.stupid.fish/notes/9shhrn2qncid008s
|
||||||
RUN git apply /patches/index-everything.patch
|
RUN git apply /patches/index-everything.patch
|
||||||
RUN git apply /patches/no-remote-users.patch
|
RUN git apply /patches/no-remote-users.patch
|
||||||
|
RUN git apply /patches/no-xpost-extension.patch
|
||||||
RUN cp -f /patches/robots.txt packages/backend/assets/robots.txt
|
RUN cp -f /patches/robots.txt packages/backend/assets/robots.txt
|
||||||
# end patch
|
# end patch
|
||||||
|
|
||||||
|
|
242
hosts/koi/containers/sharkey/patches/no-xpost-extension.patch
Normal file
242
hosts/koi/containers/sharkey/patches/no-xpost-extension.patch
Normal file
|
@ -0,0 +1,242 @@
|
||||||
|
diff --git a/packages/backend/migration/1722103475000-no-xpost.js b/packages/backend/migration/1722103475000-no-xpost.js
|
||||||
|
new file mode 100644
|
||||||
|
index 0000000..8818c37
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/packages/backend/migration/1722103475000-no-xpost.js
|
||||||
|
@@ -0,0 +1,16 @@
|
||||||
|
+/*
|
||||||
|
+ * SPDX-FileCopyrightText: syuilo and misskey-project
|
||||||
|
+ * SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+export class NoXpost1722103475000 {
|
||||||
|
+ name = 'NoXpost1722103475000'
|
||||||
|
+
|
||||||
|
+ async up(queryRunner) {
|
||||||
|
+ await queryRunner.query(`ALTER TABLE "note" ADD "noXpost" boolean NOT NULL DEFAULT false`);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ async down(queryRunner) {
|
||||||
|
+ await queryRunner.query(`ALTER TABLE "note" DROP COLUMN "noXpost"`);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
diff --git a/packages/backend/src/core/NoteCreateService.ts b/packages/backend/src/core/NoteCreateService.ts
|
||||||
|
index 41efa76..87a388e 100644
|
||||||
|
--- a/packages/backend/src/core/NoteCreateService.ts
|
||||||
|
+++ b/packages/backend/src/core/NoteCreateService.ts
|
||||||
|
@@ -149,6 +149,7 @@ type Option = {
|
||||||
|
uri?: string | null;
|
||||||
|
url?: string | null;
|
||||||
|
app?: MiApp | null;
|
||||||
|
+ noXpost?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
@@ -625,6 +626,7 @@ export class NoteCreateService implements OnApplicationShutdown {
|
||||||
|
renoteUserId: data.renote ? data.renote.userId : null,
|
||||||
|
renoteUserHost: data.renote ? data.renote.userHost : null,
|
||||||
|
userHost: user.host,
|
||||||
|
+ noXpost: data.noXpost,
|
||||||
|
});
|
||||||
|
|
||||||
|
// should really not happen, but better safe than sorry
|
||||||
|
diff --git a/packages/backend/src/core/NoteEditService.ts b/packages/backend/src/core/NoteEditService.ts
|
||||||
|
index 0cb58d0..00b4be3 100644
|
||||||
|
--- a/packages/backend/src/core/NoteEditService.ts
|
||||||
|
+++ b/packages/backend/src/core/NoteEditService.ts
|
||||||
|
@@ -141,6 +141,7 @@ type Option = {
|
||||||
|
app?: MiApp | null;
|
||||||
|
updatedAt?: Date | null;
|
||||||
|
editcount?: boolean | null;
|
||||||
|
+ noXpost?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
@@ -494,6 +495,7 @@ export class NoteEditService implements OnApplicationShutdown {
|
||||||
|
renoteUserId: data.renote ? data.renote.userId : null,
|
||||||
|
renoteUserHost: data.renote ? data.renote.userHost : null,
|
||||||
|
userHost: user.host,
|
||||||
|
+ noXpost: data.noXpost,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (data.uri != null) note.uri = data.uri;
|
||||||
|
diff --git a/packages/backend/src/core/activitypub/ApRendererService.ts b/packages/backend/src/core/activitypub/ApRendererService.ts
|
||||||
|
index 90784fd..0f9769f 100644
|
||||||
|
--- a/packages/backend/src/core/activitypub/ApRendererService.ts
|
||||||
|
+++ b/packages/backend/src/core/activitypub/ApRendererService.ts
|
||||||
|
@@ -467,6 +467,7 @@ export class ApRendererService {
|
||||||
|
attachment: files.map(x => this.renderDocument(x)),
|
||||||
|
sensitive: note.cw != null || files.some(file => file.isSensitive),
|
||||||
|
tag,
|
||||||
|
+ 'desu:no-xpost': note.noXpost,
|
||||||
|
...asPoll,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@@ -759,6 +760,7 @@ export class ApRendererService {
|
||||||
|
attachment: files.map(x => this.renderDocument(x)),
|
||||||
|
sensitive: note.cw != null || files.some(file => file.isSensitive),
|
||||||
|
tag,
|
||||||
|
+ 'desu:no-xpost': note.noXpost,
|
||||||
|
...asPoll,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
diff --git a/packages/backend/src/core/activitypub/type.ts b/packages/backend/src/core/activitypub/type.ts
|
||||||
|
index 8edd8a1..4518b27 100644
|
||||||
|
--- a/packages/backend/src/core/activitypub/type.ts
|
||||||
|
+++ b/packages/backend/src/core/activitypub/type.ts
|
||||||
|
@@ -122,6 +122,7 @@ export interface IPost extends IObject {
|
||||||
|
quoteUrl?: string;
|
||||||
|
quoteUri?: string;
|
||||||
|
updated?: string;
|
||||||
|
+ 'desu:no-xpost'?: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface IQuestion extends IObject {
|
||||||
|
diff --git a/packages/backend/src/models/Note.ts b/packages/backend/src/models/Note.ts
|
||||||
|
index b11e2ec..8cf6787 100644
|
||||||
|
--- a/packages/backend/src/models/Note.ts
|
||||||
|
+++ b/packages/backend/src/models/Note.ts
|
||||||
|
@@ -235,6 +235,11 @@ export class MiNote {
|
||||||
|
comment: '[Denormalized]',
|
||||||
|
})
|
||||||
|
public renoteUserHost: string | null;
|
||||||
|
+
|
||||||
|
+ @Column('boolean', {
|
||||||
|
+ default: false,
|
||||||
|
+ })
|
||||||
|
+ public noXpost: boolean;
|
||||||
|
//#endregion
|
||||||
|
|
||||||
|
constructor(data: Partial<MiNote>) {
|
||||||
|
diff --git a/packages/backend/src/server/api/endpoints/notes/create.ts b/packages/backend/src/server/api/endpoints/notes/create.ts
|
||||||
|
index 626f03b..451f2d8 100644
|
||||||
|
--- a/packages/backend/src/server/api/endpoints/notes/create.ts
|
||||||
|
+++ b/packages/backend/src/server/api/endpoints/notes/create.ts
|
||||||
|
@@ -155,6 +155,7 @@ export const paramDef = {
|
||||||
|
noExtractMentions: { type: 'boolean', default: false },
|
||||||
|
noExtractHashtags: { type: 'boolean', default: false },
|
||||||
|
noExtractEmojis: { type: 'boolean', default: false },
|
||||||
|
+ noXpost: { type: 'boolean', default: false },
|
||||||
|
replyId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||||
|
renoteId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||||
|
channelId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||||
|
@@ -396,6 +397,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
|
apMentions: ps.noExtractMentions ? [] : undefined,
|
||||||
|
apHashtags: ps.noExtractHashtags ? [] : undefined,
|
||||||
|
apEmojis: ps.noExtractEmojis ? [] : undefined,
|
||||||
|
+ noXpost: ps.noXpost,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
diff --git a/packages/backend/src/server/api/endpoints/notes/edit.ts b/packages/backend/src/server/api/endpoints/notes/edit.ts
|
||||||
|
index 835cbc1..ee2c787 100644
|
||||||
|
--- a/packages/backend/src/server/api/endpoints/notes/edit.ts
|
||||||
|
+++ b/packages/backend/src/server/api/endpoints/notes/edit.ts
|
||||||
|
@@ -203,6 +203,7 @@ export const paramDef = {
|
||||||
|
noExtractMentions: { type: 'boolean', default: false },
|
||||||
|
noExtractHashtags: { type: 'boolean', default: false },
|
||||||
|
noExtractEmojis: { type: 'boolean', default: false },
|
||||||
|
+ noXpost: { type: 'boolean', default: false },
|
||||||
|
replyId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||||
|
renoteId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||||
|
channelId: { type: 'string', format: 'misskey:id', nullable: true },
|
||||||
|
@@ -447,6 +448,7 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
|
||||||
|
apMentions: ps.noExtractMentions ? [] : undefined,
|
||||||
|
apHashtags: ps.noExtractHashtags ? [] : undefined,
|
||||||
|
apEmojis: ps.noExtractEmojis ? [] : undefined,
|
||||||
|
+ noXpost: ps.noXpost,
|
||||||
|
});
|
||||||
|
|
||||||
|
return {
|
||||||
|
diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue
|
||||||
|
index 57ed045..0d71611 100644
|
||||||
|
--- a/packages/frontend/src/components/MkPostForm.vue
|
||||||
|
+++ b/packages/frontend/src/components/MkPostForm.vue
|
||||||
|
@@ -203,6 +203,7 @@ const recentHashtags = ref(JSON.parse(miLocalStorage.getItem('hashtags') ?? '[]'
|
||||||
|
const imeText = ref('');
|
||||||
|
const showingOptions = ref(false);
|
||||||
|
const textAreaReadOnly = ref(false);
|
||||||
|
+const noXpost = ref(false);
|
||||||
|
|
||||||
|
const draftKey = computed((): string => {
|
||||||
|
let key = props.channel ? `channel:${props.channel.id}` : '';
|
||||||
|
@@ -471,6 +472,7 @@ function setVisibility() {
|
||||||
|
|
||||||
|
os.popup(defineAsyncComponent(() => import('@/components/MkVisibilityPicker.vue')), {
|
||||||
|
currentVisibility: visibility.value,
|
||||||
|
+ currentNoXpost: noXpost.value,
|
||||||
|
isSilenced: $i.isSilenced,
|
||||||
|
localOnly: localOnly.value,
|
||||||
|
src: visibilityButton.value,
|
||||||
|
@@ -482,6 +484,9 @@ function setVisibility() {
|
||||||
|
defaultStore.set('visibility', visibility.value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
+ changeNoXpost: v => {
|
||||||
|
+ noXpost.value = v;
|
||||||
|
+ },
|
||||||
|
}, 'closed');
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -810,6 +815,7 @@ async function post(ev?: MouseEvent) {
|
||||||
|
visibleUserIds: visibility.value === 'specified' ? visibleUsers.value.map(u => u.id) : undefined,
|
||||||
|
reactionAcceptance: reactionAcceptance.value,
|
||||||
|
editId: props.editId ? props.editId : undefined,
|
||||||
|
+ noXpost: noXpost.value,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (withHashtags.value && hashtags.value && hashtags.value.trim() !== '') {
|
||||||
|
diff --git a/packages/frontend/src/components/MkVisibilityPicker.vue b/packages/frontend/src/components/MkVisibilityPicker.vue
|
||||||
|
index e0aec8b..db25745 100644
|
||||||
|
--- a/packages/frontend/src/components/MkVisibilityPicker.vue
|
||||||
|
+++ b/packages/frontend/src/components/MkVisibilityPicker.vue
|
||||||
|
@@ -37,6 +37,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
<span :class="$style.itemDescription">{{ i18n.ts._visibility.specifiedDescription }}</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
+ <MkSwitch :modelValue="noXpost" @update:modelValue="noXpostChanged" :disabled="localOnly">
|
||||||
|
+ do not cross-post
|
||||||
|
+ </MkSwitch>
|
||||||
|
</div>
|
||||||
|
</MkModal>
|
||||||
|
</template>
|
||||||
|
@@ -45,12 +48,14 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
import { nextTick, shallowRef, ref } from 'vue';
|
||||||
|
import * as Misskey from 'misskey-js';
|
||||||
|
import MkModal from '@/components/MkModal.vue';
|
||||||
|
+import MkSwitch from '@/components/MkSwitch.vue';
|
||||||
|
import { i18n } from '@/i18n.js';
|
||||||
|
|
||||||
|
const modal = shallowRef<InstanceType<typeof MkModal>>();
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<{
|
||||||
|
currentVisibility: typeof Misskey.noteVisibilities[number];
|
||||||
|
+ currentNoXpost: boolean;
|
||||||
|
isSilenced: boolean;
|
||||||
|
localOnly: boolean;
|
||||||
|
src?: HTMLElement;
|
||||||
|
@@ -60,10 +65,12 @@ const props = withDefaults(defineProps<{
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
(ev: 'changeVisibility', v: typeof Misskey.noteVisibilities[number]): void;
|
||||||
|
+ (ev: 'changeNoXpost', v: boolean): void;
|
||||||
|
(ev: 'closed'): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const v = ref(props.currentVisibility);
|
||||||
|
+const noXpost = ref(props.currentNoXpost)
|
||||||
|
|
||||||
|
function choose(visibility: typeof Misskey.noteVisibilities[number]): void {
|
||||||
|
v.value = visibility;
|
||||||
|
@@ -72,6 +79,11 @@ function choose(visibility: typeof Misskey.noteVisibilities[number]): void {
|
||||||
|
if (modal.value) modal.value.close();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+function noXpostChanged(v: boolean): void {
|
||||||
|
+ noXpost.value = v;
|
||||||
|
+ emit('changeNoXpost', v);
|
||||||
|
+}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" module>
|
|
@ -39,11 +39,11 @@ index f849e94..9ba8351 100644
|
||||||
@@ -30,6 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
@@ -30,6 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
}]"
|
}]"
|
||||||
> <!-- we re-use t_pollEnded for "edited" instead of making an identical style -->
|
> <!-- we re-use t_pollEnded for "edited" instead of making an identical style -->
|
||||||
<i v-if="notification.type === 'follow'" class="ph-plus ph-bold ph-lg"></i>
|
<i v-if="notification.type === 'follow'" class="ti ti-plus"></i>
|
||||||
+ <i v-else-if="notification.type === 'unfollow'" class="ph-minus ph-bold ph-lg"></i>
|
+ <i v-else-if="notification.type === 'unfollow'" class="ti ti-minus"></i>
|
||||||
<i v-else-if="notification.type === 'receiveFollowRequest'" class="ph-clock ph-bold ph-lg"></i>
|
<i v-else-if="notification.type === 'receiveFollowRequest'" class="ti ti-clock"></i>
|
||||||
<i v-else-if="notification.type === 'followRequestAccepted'" class="ph-check ph-bold ph-lg"></i>
|
<i v-else-if="notification.type === 'followRequestAccepted'" class="ti ti-check"></i>
|
||||||
<i v-else-if="notification.type === 'renote'" class="ph-rocket-launch ph-bold ph-lg"></i>
|
<i v-else-if="notification.type === 'renote'" class="ti ti-repeat"></i>
|
||||||
@@ -61,6 +62,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
@@ -61,6 +62,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<span v-else-if="notification.type === 'achievementEarned'">{{ i18n.ts._notification.achievementEarned }}</span>
|
<span v-else-if="notification.type === 'achievementEarned'">{{ i18n.ts._notification.achievementEarned }}</span>
|
||||||
<span v-else-if="notification.type === 'test'">{{ i18n.ts._notification.testNotification }}</span>
|
<span v-else-if="notification.type === 'test'">{{ i18n.ts._notification.testNotification }}</span>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
--- a/packages/backend/src/server/web/views/base.pug
|
--- a/packages/backend/src/server/web/views/base.pug
|
||||||
+++ b/packages/backend/src/server/web/views/base.pug
|
+++ b/packages/backend/src/server/web/views/base.pug
|
||||||
@@ -44,5 +44,6 @@
|
@@ -44,5 +44,6 @@
|
||||||
link(rel='stylesheet' href='/static-assets/fonts/sharkey-icons/style.css')
|
link(rel='stylesheet' href=`/static-assets/fonts/sharkey-icons/style.css?version=${version}`)
|
||||||
link(rel='modulepreload' href=`/vite/${clientEntry.file}`)
|
link(rel='modulepreload' href=`/vite/${clientEntry.file}`)
|
||||||
+ script(src='https://zond.tei.su/script.js' data-website-id="9629ae3b-b086-4be1-acd2-82e2a4a58c2a")
|
+ script(src='https://zond.tei.su/script.js' data-website-id="9629ae3b-b086-4be1-acd2-82e2a4a58c2a")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue