refactor: harden types

This commit is contained in:
kakkokari-gtyih 2025-06-03 22:14:31 +09:00
parent d679d62667
commit df315b18e0
5 changed files with 20 additions and 11 deletions

View File

@ -77,6 +77,7 @@ const dialog = useTemplateRef('dialog');
async function cancel() {
if (layers.length > 0) {
const { canceled } = await os.confirm({
type: 'warning',
text: i18n.ts._imageEffector.discardChangesConfirm,
});
if (canceled) return;
@ -132,7 +133,7 @@ function onLayerDelete(layer: ImageEffectorLayer) {
const canvasEl = useTemplateRef('canvasEl');
let renderer: ImageEffector | null = null;
let renderer: ImageEffector<typeof FXS> | null = null;
let imageBitmap: ImageBitmap | null = null;
onMounted(async () => {

View File

@ -263,6 +263,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import * as Misskey from 'misskey-js';
import type { WatermarkPreset } from '@/utility/watermark.js';
import { i18n } from '@/i18n.js';
import MkButton from '@/components/MkButton.vue';
@ -277,7 +278,7 @@ import { misskeyApi } from '@/utility/misskey-api.js';
const layer = defineModel<WatermarkPreset['layers'][number]>('layer', { required: true });
const driveFile = ref();
const driveFile = ref<Misskey.entities.DriveFile | null>(null);
const driveFileError = ref(false);
onMounted(async () => {
if (layer.value.type === 'image' && layer.value.imageId != null) {
@ -300,6 +301,7 @@ function chooseFile(ev: MouseEvent) {
watermark: false,
},
}).then((file) => {
if (layer.value.type !== 'image') return;
if (!file.type.startsWith('image')) {
os.alert({
type: 'warning',

View File

@ -57,7 +57,7 @@ function getValue<T extends keyof ParamTypeToPrimitive>(params: Record<string, a
return params[k];
}
export class ImageEffector {
export class ImageEffector<IEX extends ReadonlyArray<ImageEffectorFx<any, any, any>>> {
private gl: WebGL2RenderingContext;
private canvas: HTMLCanvasElement | null = null;
private renderTextureProgram: WebGLProgram;
@ -70,7 +70,7 @@ export class ImageEffector {
private shaderCache: Map<string, WebGLProgram> = new Map();
private perLayerResultTextures: Map<string, WebGLTexture> = new Map();
private perLayerResultFrameBuffers: Map<string, WebGLFramebuffer> = new Map();
private fxs: ImageEffectorFx[];
private fxs: [...IEX];
private paramTextures: Map<string, { texture: WebGLTexture; width: number; height: number; }> = new Map();
constructor(options: {
@ -78,7 +78,7 @@ export class ImageEffector {
renderWidth: number;
renderHeight: number;
image: ImageData | ImageBitmap | HTMLImageElement | HTMLCanvasElement;
fxs: ImageEffectorFx[];
fxs: [...IEX];
}) {
this.canvas = options.canvas;
this.renderWidth = options.renderWidth;

View File

@ -35,3 +35,10 @@ export const FXS = [
FX_polkadot,
FX_checker,
] as const satisfies ImageEffectorFx<string, any>[];
export const WATERMARK_FXS = [
FX_watermarkPlacement,
FX_stripe,
FX_polkadot,
FX_checker,
] as const satisfies ImageEffectorFx<string, any>[];

View File

@ -3,10 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
import { FX_watermarkPlacement } from './image-effector/fxs/watermarkPlacement.js';
import { FX_stripe } from './image-effector/fxs/stripe.js';
import { FX_polkadot } from './image-effector/fxs/polkadot.js';
import { FX_checker } from './image-effector/fxs/checker.js';
import { WATERMARK_FXS } from './image-effector/fxs.js';
import type { ImageEffectorLayer } from '@/utility/image-effector/ImageEffector.js';
import { ImageEffector } from '@/utility/image-effector/ImageEffector.js';
@ -64,7 +61,7 @@ export type WatermarkPreset = {
};
export class WatermarkRenderer {
private effector: ImageEffector;
private effector: ImageEffector<typeof WATERMARK_FXS>;
private layers: WatermarkPreset['layers'] = [];
constructor(options: {
@ -78,7 +75,7 @@ export class WatermarkRenderer {
renderWidth: options.renderWidth,
renderHeight: options.renderHeight,
image: options.image,
fxs: [FX_watermarkPlacement, FX_stripe, FX_polkadot, FX_checker],
fxs: WATERMARK_FXS,
});
}
@ -157,6 +154,8 @@ export class WatermarkRenderer {
opacity: layer.opacity,
},
};
} else {
throw new Error(`Unknown layer type`);
}
});
}