Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Alt周りの強化 #142

Merged
merged 11 commits into from
Aug 14, 2024
7 changes: 7 additions & 0 deletions CHANGELOG_engawa.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@

### Client
- 検索ウィジェットにオートフォーカスが当たらなくなりました
- 画像がAPNGの場合GIFではなくAPNGと表示するように
- 隠すボタンのスタイル調整
- ファイル名とALTを同時に表示するように
- ALTテキストが存在する場合投稿フォームのファイルにインジケータを表示するように
- ALTテキストがない場合警告を出すオプションを追加
- 画像のタイトルには必ずファイル名を使用するように
- fix: クロッパーで画像の全体が表示されないことがある問題

### Server
- 検索機能に新しいパラメータを追加( [1673beta/cherrypick#94](https://github.com/1673beta/cherrypick/issues/94) )
Expand Down
5 changes: 5 additions & 0 deletions locales/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3024,3 +3024,8 @@ _dice:
_isIndexable:
title: "Indexable"
description: "This is kmyblue compatible feature. If you want to prevent your account from being indexed by search engines, please disable this option."

_altWarning:
noAltWarning: "ファイルに代替テキストが設定されていません。"
showNoAltWarning: "画像に代替テキストが設定されていない場合に警告を表示する"
postAnyWay: "投稿フォームへ"
14 changes: 14 additions & 0 deletions locales/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11797,6 +11797,20 @@ export interface Locale extends ILocale {
*/
"description": string;
};
"_altWarning": {
/**
* ファイルに代替テキストが設定されていません。
*/
"noAltWarning": string;
/**
* 画像に代替テキストが設定されていない場合に警告を表示する
*/
"showNoAltWarning": string;
/**
* 投稿フォームへ
*/
"postAnyWay": string;
};
}
declare const locales: {
[lang: string]: Locale;
Expand Down
5 changes: 5 additions & 0 deletions locales/ja-JP.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3149,3 +3149,8 @@ _dice:
_isIndexable:
title: "公開ノートをインデックス化"
description: "kmy互換機能。公開ノートをインデックス化するかどうかを設定します。"

_altWarning:
noAltWarning: "ファイルに代替テキストが設定されていません。"
showNoAltWarning: "画像に代替テキストが設定されていない場合に警告を表示する"
postAnyWay: "投稿フォームへ"
3 changes: 3 additions & 0 deletions packages/frontend/src/components/MkCropperDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ const onImageLoad = () => {
loading.value = false;

if (cropper) {
cropper.getCropperCanvas();
cropper.getCropperImage()!.$center('contain');
cropper.getCropperSelection()!.$center();
}
Expand Down Expand Up @@ -159,6 +160,7 @@ onMounted(() => {
width: var(--vw);
height: var(--vh);
position: relative;
object-fit: contain;

> .loading {
position: absolute;
Expand All @@ -183,6 +185,7 @@ onMounted(() => {
> ::v-deep(cropper-canvas) {
width: 100%;
height: 100%;
object-fit: contain;

> cropper-selection > cropper-handle[action="move"] {
background: transparent;
Expand Down
11 changes: 7 additions & 4 deletions packages/frontend/src/components/MkDriveFileThumbnail.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ SPDX-License-Identifier: AGPL-3.0-only

<template>
<div ref="thumbnail" :class="$style.root">
<ImgWithBlurhash v-if="isThumbnailAvailable" :hash="file.blurhash" :src="file.thumbnailUrl" :alt="file.name" :title="file.name" :cover="fit !== 'contain'"/>
<ImgWithBlurhash v-if="isThumbnailAvailable" :hash="file.blurhash" :src="file.thumbnailUrl" :alt="file.comment" :title="file.name" :cover="fit !== 'contain'" :show-alt-indicator="showAltIndicator" />
<i v-else-if="is === 'image'" class="ti ti-photo" :class="$style.icon"></i>
<i v-else-if="is === 'video'" class="ti ti-video" :class="$style.icon"></i>
<i v-else-if="is === 'audio' || is === 'midi'" class="ti ti-file-music" :class="$style.icon"></i>
Expand All @@ -24,10 +24,13 @@ import { computed } from 'vue';
import * as Misskey from 'cherrypick-js';
import ImgWithBlurhash from '@/components/MkImgWithBlurhash.vue';

const props = defineProps<{
const props = withDefaults(defineProps<{
file: Misskey.entities.DriveFile;
fit: 'cover' | 'contain';
}>();
fit: string;
showAltIndicator: boolean;
}>(), {
showAltIndicator: false,
})

const is = computed(() => {
if (props.file.type.startsWith('image/')) return 'image';
Expand Down
20 changes: 20 additions & 0 deletions packages/frontend/src/components/MkImgWithBlurhash.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ SPDX-License-Identifier: AGPL-3.0-only
>
<canvas v-show="hide" key="canvas" ref="canvas" :class="$style.canvas" :width="canvasWidth" :height="canvasHeight" :title="title ?? undefined" tabindex="-1"/>
<img v-show="!hide" key="img" ref="img" :height="imgHeight ?? undefined" :width="imgWidth ?? undefined" :class="[$style.img, { [$style.noDrag]: noDrag }]" :src="src ?? undefined" :title="title ?? undefined" :alt="alt ?? undefined" loading="eager" decoding="async" tabindex="-1"/>
<i v-if="alt && showAltIndicator" :class="$style.altIndicator" class="ti ti-alt"></i>
</TransitionGroup>
</div>
</template>
Expand Down Expand Up @@ -82,6 +83,7 @@ const props = withDefaults(defineProps<{
forceBlurhash?: boolean;
onlyAvgColor?: boolean; // 軽量化のためにBlurhashを使わずに平均色だけを描画
noDrag?: boolean;
showAltIndicator?: boolean;
}>(), {
transition: null,
src: null,
Expand All @@ -93,6 +95,7 @@ const props = withDefaults(defineProps<{
forceBlurhash: false,
onlyAvgColor: false,
noDrag: false,
showAltIndicator: false,
});

const viewId = uuid();
Expand Down Expand Up @@ -269,4 +272,21 @@ onUnmounted(() => {
-webkit-user-drag: none;
}
}

.altIndicator {
display: flex;
gap: 4px;
position: absolute;
border-radius: 8px;
overflow: hidden;
top: 0;
right: 0;
background-color: var(--bg);
-webkit-backdrop-filter: var(--blur, blur(15px));
backdrop-filter: var(--blur, blur(15px));
color: var(--accent);
font-size: 1em;
padding: 6px 8px;
text-align: center;
}
</style>
9 changes: 5 additions & 4 deletions packages/frontend/src/components/MkMediaImage.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ SPDX-License-Identifier: AGPL-3.0-only
:forceBlurhash="hide"
:cover="hide || cover"
:alt="image.comment || image.name"
:title="image.comment || image.name"
:title="image.name"
:width="image.properties.width"
:height="image.properties.height"
:style="hide ? 'filter: brightness(0.7);' : null"
Expand All @@ -44,7 +44,8 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<template v-else-if="controls">
<div :class="$style.indicators">
<div v-if="['image/gif', 'image/apng'].includes(image.type)" :class="$style.indicator">GIF</div>
<div v-if="['image/gif'].includes(image.type)" :class="$style.indicator">GIF</div>
<div v-if="['image/apng'].includes(image.type)" :class="$style.indicator">APNG</div>
<div v-if="image.comment" :class="$style.indicator">ALT</div>
<div v-if="image.isSensitive" :class="$style.indicator" style="color: var(--warn);" :title="i18n.ts.sensitive"><i class="ti ti-eye-exclamation"></i></div>
</div>
Expand Down Expand Up @@ -220,9 +221,9 @@ onUnmounted(() => {
display: block;
position: absolute;
border-radius: 6px;
background-color: var(--fg);
background-color: var(--bg);
color: var(--accentLighten);
font-size: 12px;
font-size: 18px;
opacity: .5;
padding: 5px 8px;
text-align: center;
Expand Down
53 changes: 51 additions & 2 deletions packages/frontend/src/components/MkMediaList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,9 @@ onMounted(() => {
[itemData.w, itemData.h] = [itemData.h, itemData.w];
}
itemData.msrc = file.thumbnailUrl ?? undefined;
itemData.alt = file.comment ?? file.name;
itemData.alt = file.comment || undefined;
itemData.comment = file.comment ?? file.name;
itemData.title = file.name;
itemData.thumbCropped = true;

return itemData;
Expand All @@ -179,7 +180,25 @@ onMounted(() => {
el.appendChild(textBox);

pswp.on('change', () => {
textBox.textContent = pswp.currSlide?.data.comment;
const altText = pswp.currSlide?.data.alt || null;
textBox.textContent = altText;
if (!altText) {
el.style.display = 'none';
}
});
},
});
lightbox?.pswp?.ui?.registerElement({
name: 'fileName',
className: 'pswp__file-name-container',
appendTo: 'wrapper',
onInit: (el, pswp) => {
const textBox = document.createElement('p');
textBox.className = 'pswp__file-name _acrylic';
el.appendChild(textBox);

pswp.on('change', () => {
textBox.textContent = pswp.currSlide?.data.title;
});
},
});
Expand Down Expand Up @@ -338,13 +357,31 @@ defineExpose({
flex-direction: row;
align-items: center;

position: absolute;
bottom: 100px;
left: 50%;
transform: translateX(-50%);

width: 75%;
max-width: 800px;

z-index: 2;
}

.pswp__file-name-container {
display: flex;
flex-direction: row;
align-items: center;

position: absolute;
bottom: 20px;
left: 50%;
transform: translateX(-50%);

width: 75%;
max-width: 800px;

z-index: 1;
}

.pswp__alt-text {
Expand All @@ -358,4 +395,16 @@ defineExpose({
text-shadow: var(--bg) 0 0 10px, var(--bg) 0 0 3px, var(--bg) 0 0 3px;
white-space: pre-line;
}

.pswp__file-name {
color: var(--fg);
margin: 0 auto;
text-align: center;
padding: var(--margin);
border-radius: var(--radius);
max-height: 16em;
overflow-y: auto;
text-shadow: var(--bg) 0 0 10px, var(--bg) 0 0 3px, var(--bg) 0 0 3px;
white-space: pre-line;
}
</style>
13 changes: 12 additions & 1 deletion packages/frontend/src/components/MkPostForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ import { emojiPicker } from '@/scripts/emoji-picker.js';
import { vibrate } from '@/scripts/vibrate.js';
import * as sound from '@/scripts/sound.js';
import { mfmFunctionPicker } from '@/scripts/mfm-function-picker.js';
import { file } from '.storybook/fakes';


const $i = signinRequired();
Expand Down Expand Up @@ -183,7 +184,7 @@ const visibilityButton = shallowRef<HTMLElement>();
const posting = ref(false);
const posted = ref(false);
const text = ref(props.initialText ?? '');
const files = ref(props.initialFiles ?? []);
const files = ref(props.initialFiles ?? ([] as Misskey.entities.DriveFile[]));
const poll = ref<PollEditorModelValue | null>(null);
const event = ref<{
title: string;
Expand Down Expand Up @@ -791,6 +792,16 @@ async function post(ev?: MouseEvent) {
});
return;
}
if (defaultStore.state.showNoAltTextWarning && files.value.some((f) => f.comment == null || f.comment.length === 0)) {
const { canceled } = await os.confirm({
type: 'warning',
text: i18n.ts._altWarning.noAltWarning,
okText: i18n.ts.goBack,
cancelText: i18n.ts._altWarning.postAnyWay,
});

if (!canceled) return;
}

if (ev) {
const el = (ev.currentTarget ?? ev.target) as HTMLElement | null;
Expand Down
2 changes: 1 addition & 1 deletion packages/frontend/src/components/MkPostFormAttaches.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<Sortable :modelValue="props.modelValue" :class="$style.files" itemKey="id" :animation="150" :delay="100" :delayOnTouchOnly="true" @update:modelValue="v => emit('update:modelValue', v)">
<template #item="{element}">
<div :class="$style.file" @click="showFileMenu(element, $event)" @contextmenu.prevent="showFileMenu(element, $event)">
<MkDriveFileThumbnail :data-id="element.id" :class="$style.thumbnail" :file="element" fit="cover"/>
<MkDriveFileThumbnail :data-id="element.id" :class="$style.thumbnail" :file="element" fit="cover" :show-alt-indicator="true" />
<div v-if="element.isSensitive" :class="$style.sensitive">
<i class="ti ti-eye-exclamation" style="margin: auto;"></i>
</div>
Expand Down
2 changes: 2 additions & 0 deletions packages/frontend/src/pages/settings/general.vue
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</MkSelect>
<MkSwitch v-model="showFixedPostFormInReplies">{{ i18n.ts.showFixedPostFormInReplies }}<template #caption>{{ i18n.ts.showFixedPostFormInRepliesDescription }}</template> <span class="_beta">CherryPick</span></MkSwitch>
<MkSwitch v-model="allMediaNoteCollapse">{{ i18n.ts.allMediaNoteCollapse }} <span class="_beta">CherryPick</span></MkSwitch>
<MkSwitch v-model="showNoAltTextWarning">{{ i18n.ts._altWarning.showNoAltWarning }}</MkSwitch>
</div>

<MkSelect v-model="instanceTicker">
Expand Down Expand Up @@ -471,6 +472,7 @@ const allMediaNoteCollapse = computed(defaultStore.makeGetterSetter('allMediaNot
const nsfwOpenBehavior = computed(defaultStore.makeGetterSetter('nsfwOpenBehavior'));
const renoteVisibilitySelection = computed(defaultStore.makeGetterSetter('renoteVisibilitySelection'));
const forceRenoteVisibilitySelection = computed(defaultStore.makeGetterSetter('forceRenoteVisibilitySelection'));
const showNoAltTextWarning = computed(defaultStore.makeGetterSetter('showNoAltTextWarning'));

watch(lang, () => {
miLocalStorage.setItem('lang', lang.value as string);
Expand Down
4 changes: 4 additions & 0 deletions packages/frontend/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,10 @@ export const defaultStore = markRaw(new Storage('base', {
where: 'account',
default: [] as string[],
},
showNoAltTextWarning: {
where: 'account',
default: true,
},

menu: {
where: 'deviceAccount',
Expand Down
Loading