forked from mirrors/misskey
feat(frontend): EXIFフレーム機能 (#16725)
* wip
* wip
* Update ImageEffector.ts
* Update image-label-renderer.ts
* Update image-label-renderer.ts
* wip
* Update image-label-renderer.ts
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* Update use-uploader.ts
* Update watermark.ts
* wip
* wu
* wip
* Update image-frame-renderer.ts
* wip
* wip
* Update image-frame-renderer.ts
* Create ImageCompositor.ts
* Update ImageCompositor.ts
* wip
* wip
* Update ImageEffector.ts
* wip
* Update use-uploader.ts
* wip
* wip
* wip
* wip
* Update fxs.ts
* wip
* wip
* wip
* Update CHANGELOG.md
* wip
* wip
* Update MkImageEffectorDialog.vue
* Update MkImageEffectorDialog.vue
* Update MkImageFrameEditorDialog.vue
* Update use-uploader.ts
* improve error handling
* Update use-uploader.ts
* 🎨
* wip
* wip
* lazy load
* lazy load
* wip
* wip
* wip
This commit is contained in:
@@ -124,6 +124,34 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||
</MkFolder>
|
||||
</SearchMarker>
|
||||
|
||||
<SearchMarker :keywords="['label', 'frame', 'credit', 'metadata']">
|
||||
<MkFolder>
|
||||
<template #icon><i class="ti ti-device-ipad-horizontal"></i></template>
|
||||
<template #label><SearchLabel>{{ i18n.ts.frame }}</SearchLabel></template>
|
||||
<template #caption>{{ i18n.ts._imageFrameEditor.tip }}</template>
|
||||
|
||||
<div class="_gaps">
|
||||
<div class="_gaps_s">
|
||||
<XImageFrameItem
|
||||
v-for="(preset, i) in prefer.r.imageFramePresets.value"
|
||||
:key="preset.id"
|
||||
:preset="preset"
|
||||
@updatePreset="onUpdateImageFramePreset(preset.id, $event)"
|
||||
@del="onDeleteImageFramePreset(preset.id)"
|
||||
/>
|
||||
|
||||
<MkButton iconOnly rounded style="margin: 0 auto;" @click="addImageFramePreset"><i class="ti ti-plus"></i></MkButton>
|
||||
|
||||
<SearchMarker :keywords="['sync', 'frame', 'label', 'preset', 'devices']">
|
||||
<MkSwitch :modelValue="imageFramePresetsSyncEnabled" @update:modelValue="changeImageFramePresetsSyncEnabled">
|
||||
<template #label><i class="ti ti-cloud-cog"></i> <SearchLabel>{{ i18n.ts.syncBetweenDevices }}</SearchLabel></template>
|
||||
</MkSwitch>
|
||||
</SearchMarker>
|
||||
</div>
|
||||
</div>
|
||||
</MkFolder>
|
||||
</SearchMarker>
|
||||
|
||||
<SearchMarker :keywords="['default', 'image', 'compression']">
|
||||
<MkPreferenceContainer k="defaultImageCompressionLevel">
|
||||
<MkSelect
|
||||
@@ -175,7 +203,9 @@ import { computed, defineAsyncComponent, ref } from 'vue';
|
||||
import * as Misskey from 'misskey-js';
|
||||
import tinycolor from 'tinycolor2';
|
||||
import XWatermarkItem from './drive.WatermarkItem.vue';
|
||||
import type { WatermarkPreset } from '@/utility/watermark.js';
|
||||
import XImageFrameItem from './drive.ImageFrameItem.vue';
|
||||
import type { WatermarkPreset } from '@/utility/watermark/WatermarkRenderer.js';
|
||||
import type { ImageFramePreset } from '@/utility/image-frame-renderer/ImageFrameRenderer.js';
|
||||
import FormLink from '@/components/form/link.vue';
|
||||
import MkSwitch from '@/components/MkSwitch.vue';
|
||||
import MkSelect from '@/components/MkSelect.vue';
|
||||
@@ -195,6 +225,7 @@ import MkFeatureBanner from '@/components/MkFeatureBanner.vue';
|
||||
import { selectDriveFolder } from '@/utility/drive.js';
|
||||
import MkFolder from '@/components/MkFolder.vue';
|
||||
import MkButton from '@/components/MkButton.vue';
|
||||
import { genId } from '@/utility/id.js';
|
||||
|
||||
const $i = ensureSignin();
|
||||
|
||||
@@ -236,6 +267,20 @@ function changeWatermarkPresetsSyncEnabled(value: boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
const imageFramePresetsSyncEnabled = ref(prefer.isSyncEnabled('imageFramePresets'));
|
||||
|
||||
function changeImageFramePresetsSyncEnabled(value: boolean) {
|
||||
if (value) {
|
||||
prefer.enableSync('imageFramePresets').then((res) => {
|
||||
if (res == null) return;
|
||||
if (res.enabled) imageFramePresetsSyncEnabled.value = true;
|
||||
});
|
||||
} else {
|
||||
prefer.disableSync('imageFramePresets');
|
||||
imageFramePresetsSyncEnabled.value = false;
|
||||
}
|
||||
}
|
||||
|
||||
misskeyApi('drive').then(info => {
|
||||
capacity.value = info.capacity;
|
||||
usage.value = info.usage;
|
||||
@@ -266,8 +311,11 @@ function chooseUploadFolder() {
|
||||
|
||||
async function addWatermarkPreset() {
|
||||
const { dispose } = await os.popupAsyncWithDialog(import('@/components/MkWatermarkEditorDialog.vue').then(x => x.default), {
|
||||
presetEditMode: true,
|
||||
preset: null,
|
||||
layers: [],
|
||||
}, {
|
||||
ok: (preset: WatermarkPreset) => {
|
||||
presetOk: (preset) => {
|
||||
prefer.commit('watermarkPresets', [...prefer.s.watermarkPresets, preset]);
|
||||
},
|
||||
closed: () => dispose(),
|
||||
@@ -299,6 +347,40 @@ function onDeleteWatermarkPreset(id: string) {
|
||||
}
|
||||
}
|
||||
|
||||
function onUpdateImageFramePreset(id: string, preset: ImageFramePreset) {
|
||||
const index = prefer.s.imageFramePresets.findIndex(p => p.id === id);
|
||||
if (index !== -1) {
|
||||
prefer.commit('imageFramePresets', [
|
||||
...prefer.s.imageFramePresets.slice(0, index),
|
||||
preset,
|
||||
...prefer.s.imageFramePresets.slice(index + 1),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
function onDeleteImageFramePreset(id: string) {
|
||||
const index = prefer.s.imageFramePresets.findIndex(p => p.id === id);
|
||||
if (index !== -1) {
|
||||
prefer.commit('imageFramePresets', [
|
||||
...prefer.s.imageFramePresets.slice(0, index),
|
||||
...prefer.s.imageFramePresets.slice(index + 1),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
async function addImageFramePreset() {
|
||||
const { dispose } = await os.popupAsyncWithDialog(import('@/components/MkImageFrameEditorDialog.vue').then(x => x.default), {
|
||||
presetEditMode: true,
|
||||
preset: null,
|
||||
params: null,
|
||||
}, {
|
||||
presetOk: (preset) => {
|
||||
prefer.commit('imageFramePresets', [...prefer.s.imageFramePresets, preset]);
|
||||
},
|
||||
closed: () => dispose(),
|
||||
});
|
||||
}
|
||||
|
||||
function saveProfile() {
|
||||
misskeyApi('i/update', {
|
||||
alwaysMarkNsfw: !!alwaysMarkNsfw.value,
|
||||
|
||||
Reference in New Issue
Block a user