This commit is contained in:
syuilo 2025-05-13 12:00:05 +09:00
parent 5a8cd627ef
commit 988ebb8aaa
3 changed files with 42 additions and 3 deletions

10
locales/index.d.ts vendored
View File

@ -11902,6 +11902,16 @@ export interface Locale extends ILocale {
"text3": string; "text3": string;
}; };
}; };
"_uploader": {
/**
* {x}
*/
"compressedToX": ParameterizedString<"x">;
/**
* {x}%
*/
"savedXPercent": ParameterizedString<"x">;
};
} }
declare const locales: { declare const locales: {
[lang: string]: Locale; [lang: string]: Locale;

View File

@ -3182,3 +3182,7 @@ _serverSetupWizard:
text1: "Misskeyは有志によって開発されている無料のソフトウェアです。" text1: "Misskeyは有志によって開発されている無料のソフトウェアです。"
text2: "今後も開発を続けられるように、よろしければぜひカンパをお願いいたします。" text2: "今後も開発を続けられるように、よろしければぜひカンパをお願いいたします。"
text3: "支援者向け特典もあります!" text3: "支援者向け特典もあります!"
_uploader:
compressedToX: "{x}に圧縮"
savedXPercent: "{x}%節約"

View File

@ -17,7 +17,13 @@ SPDX-License-Identifier: AGPL-3.0-only
<div :class="$style.root" class="_gaps_s"> <div :class="$style.root" class="_gaps_s">
<div :class="$style.items" class="_gaps_s"> <div :class="$style.items" class="_gaps_s">
<div v-for="ctx in items" :key="ctx.id" v-panel :class="[$style.item, ctx.waiting ? $style.itemWaiting : null]" :style="{ '--p': ctx.progressValue !== null ? `${ctx.progressValue / ctx.progressMax * 100}%` : '0%' }"> <div
v-for="ctx in items"
:key="ctx.id"
v-panel
:class="[$style.item, ctx.waiting ? $style.itemWaiting : null, ctx.uploaded ? $style.itemCompleted : null, ctx.uploadFailed ? $style.itemFailed : null]"
:style="{ '--p': ctx.progressValue !== null ? `${ctx.progressValue / ctx.progressMax * 100}%` : '0%' }"
>
<div :class="$style.itemInner"> <div :class="$style.itemInner">
<div> <div>
<MkButton :iconOnly="true" rounded @click="showMenu($event, ctx)"><i class="ti ti-dots"></i></MkButton> <MkButton :iconOnly="true" rounded @click="showMenu($event, ctx)"><i class="ti ti-dots"></i></MkButton>
@ -27,7 +33,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<div>{{ ctx.name }}</div> <div>{{ ctx.name }}</div>
<div :class="$style.itemInfo"> <div :class="$style.itemInfo">
<span>{{ bytes(ctx.file.size) }}</span> <span>{{ bytes(ctx.file.size) }}</span>
<span v-if="ctx.compressedSize">({{ bytes(ctx.compressedSize) }})</span> <span v-if="ctx.compressedSize">({{ i18n.tsx._uploader.compressedToX({ x: bytes(ctx.compressedSize) }) }} = {{ i18n.tsx._uploader.savedXPercent({ x: Math.round((1 - ctx.compressedSize / ctx.file.size) * 100) }) }})</span>
</div> </div>
<div> <div>
</div> </div>
@ -181,6 +187,7 @@ async function upload() { // エラーハンドリングなどを考慮してシ
for (const item of items.value.filter(item => item.uploaded == null)) { for (const item of items.value.filter(item => item.uploaded == null)) {
item.waiting = true; item.waiting = true;
item.uploadFailed = false;
const shouldCompress = item.compressedImage == null && compressionLevel.value !== 0 && compressionSettings.value && compressionSupportedTypes.includes(item.file.type) && !(await isAnimated(item.file)); const shouldCompress = item.compressedImage == null && compressionLevel.value !== 0 && compressionSettings.value && compressionSupportedTypes.includes(item.file.type) && !(await isAnimated(item.file));
@ -272,7 +279,7 @@ onMounted(() => {
width: var(--p); width: var(--p);
height: 100%; height: 100%;
background: color(from var(--MI_THEME-accent) srgb r g b / 0.5); background: color(from var(--MI_THEME-accent) srgb r g b / 0.5);
transition: width 0.2s ease; transition: width 0.2s ease, left 0.2s ease;
} }
&.itemWaiting { &.itemWaiting {
@ -291,6 +298,23 @@ onMounted(() => {
animation: stripe .8s infinite linear; animation: stripe .8s infinite linear;
} }
} }
&.itemCompleted {
&::before {
left: 100%;
width: var(--p);
}
.itemBody {
color: var(--MI_THEME-accent);
}
}
&.itemFailed {
.itemBody {
color: var(--MI_THEME-error);
}
}
} }
@keyframes stripe { @keyframes stripe {
@ -310,6 +334,7 @@ onMounted(() => {
.itemThumbnail { .itemThumbnail {
width: 70px; width: 70px;
height: 70px; height: 70px;
background-color: var(--MI_THEME-bg);
background-size: contain; background-size: contain;
background-position: center; background-position: center;
background-repeat: no-repeat; background-repeat: no-repeat;