Skip to content

Commit

Permalink
feat: multi tab by episode group in SubjectDetails.vue when episode c…
Browse files Browse the repository at this point in the history
…ount gt 20 (#655)

* optimize: default theme simple

* feat: multi tab by episode group in SubjectDetails.vue when episode count gt 20

* feat: add ep group for AttachmentReferenceService.matchingAttachmentsAndSubjectEpisodes

* feat: hide episode matching btn in SubjectDetails.vue for ep group not MAIN.

* docs: update CHANGELOG.MD
  • Loading branch information
chivehao committed Aug 16, 2024
1 parent 4669a22 commit 0403477
Show file tree
Hide file tree
Showing 45 changed files with 1,931 additions and 1,136 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.MD
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@

# 0.15.4

## 新特性

- Console条目详情页剧集过多时分TAB #654
- Console条目详情页其它剧集分组隐藏批量匹配按钮

## 主题

- 修复默认主题剧集序号选择问题
Expand Down
86 changes: 48 additions & 38 deletions console/src/components/image/Cropperjs.vue
Original file line number Diff line number Diff line change
@@ -1,69 +1,79 @@
<script setup lang="ts">
import Cropper from 'cropperjs';
import "cropperjs/dist/cropper.css";
import 'cropperjs/dist/cropper.css';
import {onMounted, ref, watch} from 'vue';
const props = withDefaults(
defineProps<{
url: string;
aspectRatio?: number;
aspectRatio?: number;
}>(),
{
url: '',
aspectRatio: 430 / 600,
aspectRatio: 430 / 600,
}
);
const emit = defineEmits<{
// eslint-disable-next-line no-unused-vars
(event: 'clip-img', base64Encode: string | undefined): void;
}>();
watch(props, (val)=>{
cropper.value?.setAspectRatio(val.aspectRatio);
cropper.value?.replace(val.url);
})
watch(props, (val) => {
cropper.value?.setAspectRatio(val.aspectRatio);
cropper.value?.replace(val.url);
});
const croimg = ref({});
const cropper = ref<Cropper>();
const clipImgEmitBase64 = (cvs: HTMLCanvasElement) => {
if (!cvs) return;
const base64 = cvs.toDataURL('image/webp', 1);
emit('clip-img', base64);
}
if (!cvs) return;
const base64 = cvs.toDataURL('image/webp', 1);
emit('clip-img', base64);
};
onMounted(()=>{
cropper.value = new Cropper(croimg.value as HTMLImageElement, {
aspectRatio: props.aspectRatio,
viewMode: 1,
dragMode: 'move',
autoCropArea: 1,
ready(){
clipImgEmitBase64(cropper.value?.getCroppedCanvas({imageSmoothingQuality: 'high'}) as HTMLCanvasElement);
},
cropend(){
clipImgEmitBase64(cropper.value?.getCroppedCanvas({imageSmoothingQuality: 'high'}) as HTMLCanvasElement);
},
zoom(){
clipImgEmitBase64(cropper.value?.getCroppedCanvas({imageSmoothingQuality: 'high'}) as HTMLCanvasElement);
},
})
})
onMounted(() => {
cropper.value = new Cropper(croimg.value as HTMLImageElement, {
aspectRatio: props.aspectRatio,
viewMode: 1,
dragMode: 'move',
autoCropArea: 1,
ready() {
clipImgEmitBase64(
cropper.value?.getCroppedCanvas({
imageSmoothingQuality: 'high',
}) as HTMLCanvasElement
);
},
cropend() {
clipImgEmitBase64(
cropper.value?.getCroppedCanvas({
imageSmoothingQuality: 'high',
}) as HTMLCanvasElement
);
},
zoom() {
clipImgEmitBase64(
cropper.value?.getCroppedCanvas({
imageSmoothingQuality: 'high',
}) as HTMLCanvasElement
);
},
});
});
</script>
<template>
<div>
<img ref="croimg" class="fit img" :src="props.url" />
</div>
<div>
<img ref="croimg" class="fit img" :src="props.url" />
</div>
</template>
<style lang="scss" scoped>
.img {
display: block;
// object-fit: contain;
max-width: 100%;
// width: 100%;
// height: 100%;
display: block;
// object-fit: contain;
max-width: 100%;
// width: 100%;
// height: 100%;
}
</style>
78 changes: 32 additions & 46 deletions console/src/components/image/CropperjsDialog.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ import {ElButton, ElDialog} from 'element-plus';
import {apiClient} from '@/utils/api-client';
import {randomUUID} from '@/utils/id';
const props = withDefaults(
defineProps<{
visible: boolean;
url: string;
url: string;
}>(),
{
visible: false,
url: '',
url: '',
}
);
Expand All @@ -22,8 +21,8 @@ const emit = defineEmits<{
(event: 'update:visible', visible: boolean): void;
// eslint-disable-next-line no-unused-vars
(event: 'close'): void;
// eslint-disable-next-line no-unused-vars
(event: 'updateUrl', newUrl: string): void;
// eslint-disable-next-line no-unused-vars
(event: 'updateUrl', newUrl: string): void;
}>();
const dialogVisible = computed({
Expand All @@ -39,56 +38,43 @@ const onClose = () => {
emit('close');
};
const base64 = ref('')
const base64 = ref('');
const onClipImg = (base64Encode) => {
base64.value = base64Encode;
}
base64.value = base64Encode;
};
const onConfirm = async () => {
if (!base64.value) return;
const file = base64ToFile(base64.value as string, randomUUID() + '.webp');
const {data} = await apiClient.attachment.uploadAttachment({
file: file
});
emit('updateUrl', data.url as string);
dialogVisible.value = false;
}
if (!base64.value) return;
const file = base64ToFile(base64.value as string, randomUUID() + '.webp');
const { data } = await apiClient.attachment.uploadAttachment({
file: file,
});
emit('updateUrl', data.url as string);
dialogVisible.value = false;
};
const base64ToFile = (base64, filename): File => {
const arr = base64.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
const arr = base64.split(',');
const mime = arr[0].match(/:(.*?);/)[1];
const bstr = atob(arr[1]);
let n = bstr.length;
const u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, {type: mime});
}
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
};
</script>
<template>
<el-dialog
v-model="dialogVisible"
title="Clip image"
@close="onClose"
>
<Cropperjs :url="props.url" @clip-img="onClipImg"/>
<template #footer>
<el-dialog v-model="dialogVisible" title="Clip image" @close="onClose">
<Cropperjs :url="props.url" @clip-img="onClipImg" />
<template #footer>
<span>
<el-button
plain
@click="onConfirm"
>
Confirm
</el-button>
<el-button plain @click="onConfirm"> Confirm </el-button>
</span>
</template>
</el-dialog>

</template>
</el-dialog>
</template>
<style lang="scss" scoped>
</style>
<style lang="scss" scoped></style>
Loading

0 comments on commit 0403477

Please sign in to comment.