merge: Add option to keep CWs with "RE:" prefix (!1093)

View MR for information: https://activitypub.software/TransFem-org/Sharkey/-/merge_requests/1093

Approved-by: dakkar <dakkar@thenautilus.net>
Approved-by: Marie <github@yuugi.dev>
This commit is contained in:
Hazelnoot 2025-06-04 19:48:00 +00:00
commit dc35731589
6 changed files with 51 additions and 22 deletions

16
locales/index.d.ts vendored
View file

@ -13217,6 +13217,22 @@ export interface Locale extends ILocale {
* Hibernated * Hibernated
*/ */
"hibernated": string; "hibernated": string;
/**
* When replying to a post with a Content Warning, automatically use the same CW for the reply.
*/
"keepCwDescription": string;
/**
* Disabled (do not copy CWs)
*/
"keepCwDisabled": string;
/**
* Enabled (copy CWs verbatim)
*/
"keepCwEnabled": string;
/**
* Enabled (copy CW and prepend "RE:")
*/
"keepCwPrependRe": string;
} }
declare const locales: { declare const locales: {
[lang: string]: Locale; [lang: string]: Locale;

View file

@ -373,7 +373,9 @@ if (props.specified) {
// keep cw when reply // keep cw when reply
if (prefer.s.keepCw && props.reply && props.reply.cw) { if (prefer.s.keepCw && props.reply && props.reply.cw) {
useCw.value = true; useCw.value = true;
cw.value = props.reply.cw; cw.value = prefer.s.keepCw === 'prepend-re'
? `RE: ${props.reply.cw}`
: props.reply.cw;
} }
// apply default CW // apply default CW

View file

@ -39,32 +39,34 @@ SPDX-License-Identifier: AGPL-3.0-only
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts">
type ItemOption<T extends string | number | null | boolean = string | number | null> = {
type?: 'option';
value: T;
label: string;
};
type ItemGroup<T extends string | number | null | boolean = string | number | null> = {
type: 'group';
label: string;
items: ItemOption<T>[];
};
export type MkSelectItem<T extends string | number | null | boolean = string | number | null> = ItemOption<T> | ItemGroup<T>;
</script>
<script lang="ts" setup generic="T extends string | number | null | boolean = string | number | null">
import { onMounted, nextTick, ref, watch, computed, toRefs, useSlots } from 'vue'; import { onMounted, nextTick, ref, watch, computed, toRefs, useSlots } from 'vue';
import { useInterval } from '@@/js/use-interval.js'; import { useInterval } from '@@/js/use-interval.js';
import type { VNode, VNodeChild } from 'vue'; import type { VNode, VNodeChild } from 'vue';
import type { MenuItem } from '@/types/menu.js'; import type { MenuItem } from '@/types/menu.js';
import * as os from '@/os.js'; import * as os from '@/os.js';
type ItemOption = {
type?: 'option';
value: string | number | null;
label: string;
};
type ItemGroup = {
type: 'group';
label: string;
items: ItemOption[];
};
export type MkSelectItem = ItemOption | ItemGroup;
// TODO: itemsslotoption(props.items) // TODO: itemsslotoption(props.items)
// see: https://github.com/misskey-dev/misskey/issues/15558 // see: https://github.com/misskey-dev/misskey/issues/15558
const props = defineProps<{ const props = defineProps<{
modelValue: string | number | null; modelValue: T;
required?: boolean; required?: boolean;
readonly?: boolean; readonly?: boolean;
disabled?: boolean; disabled?: boolean;
@ -73,11 +75,11 @@ const props = defineProps<{
inline?: boolean; inline?: boolean;
small?: boolean; small?: boolean;
large?: boolean; large?: boolean;
items?: MkSelectItem[]; items?: MkSelectItem<T>[];
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
(ev: 'update:modelValue', value: string | number | null): void; (ev: 'update:modelValue', value: T): void;
}>(); }>();
const slots = useSlots(); const slots = useSlots();

View file

@ -403,9 +403,13 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="_gaps_s"> <div class="_gaps_s">
<SearchMarker :keywords="['remember', 'keep', 'note', 'cw']"> <SearchMarker :keywords="['remember', 'keep', 'note', 'cw']">
<MkPreferenceContainer k="keepCw"> <MkPreferenceContainer k="keepCw">
<MkSwitch v-model="keepCw"> <MkSelect v-model="keepCw">
<template #label><SearchLabel>{{ i18n.ts.keepCw }}</SearchLabel></template> <template #label><SearchLabel>{{ i18n.ts.keepCw }}</SearchLabel></template>
</MkSwitch> <template #caption><SearchKeyword>{{ i18n.ts.keepCwDescription }}</SearchKeyword></template>
<option :value="false">{{ i18n.ts.keepCwDisabled }}</option>>
<option :value="true">{{ i18n.ts.keepCwEnabled }}</option>>
<option value="prepend-re">{{ i18n.ts.keepCwPrependRe }}</option>
</MkSelect>
</MkPreferenceContainer> </MkPreferenceContainer>
</SearchMarker> </SearchMarker>

View file

@ -120,7 +120,7 @@ export const PREF_DEF = {
default: false, default: false,
}, },
keepCw: { keepCw: {
default: true, default: true as boolean | 'prepend-re',
}, },
rememberNoteVisibility: { rememberNoteVisibility: {
default: false, default: false,

View file

@ -614,3 +614,8 @@ bubble: "Bubble"
verified: "Verified" verified: "Verified"
notVerified: "Not Verified" notVerified: "Not Verified"
hibernated: "Hibernated" hibernated: "Hibernated"
keepCwDescription: "When replying to a post with a Content Warning, automatically use the same CW for the reply."
keepCwDisabled: "Disabled (do not copy CWs)"
keepCwEnabled: "Enabled (copy CWs verbatim)"
keepCwPrependRe: "Enabled (copy CW and prepend \"RE:\")"