refactor: media-caption component as composition api

This commit is contained in:
Norm 2022-07-21 23:11:17 -04:00 committed by Gitea
parent 0ae09f2e80
commit b64f266483

View file

@ -16,7 +16,7 @@
</div>
<div class="hdrwpsaf fullwidth">
<header>{{ image.name }}</header>
<img :src="image.url" :alt="image.comment" :title="image.comment" @click="$refs.modal.close()"/>
<img :src="image.url" :alt="image.comment" :title="image.comment" @click="modal.close()"/>
<footer>
<span>{{ image.type }}</span>
<span>{{ bytes(image.size) }}</span>
@ -27,111 +27,85 @@
</MkModal>
</template>
<script lang="ts">
import { defineComponent } from 'vue';
<script lang="ts" setup>
import { onBeforeUnmount, onMounted, computed } from 'vue';
import { length } from 'stringz';
import * as misskey from 'misskey-js';
import MkModal from '@/components/ui/modal.vue';
import MkButton from '@/components/ui/button.vue';
import bytes from '@/filters/bytes';
import number from '@/filters/number';
export default defineComponent({
components: {
MkModal,
MkButton,
},
props: {
image: {
type: Object,
required: true,
},
title: {
type: String,
required: false
},
input: {
required: true
},
showOkButton: {
type: Boolean,
default: true
},
showCancelButton: {
type: Boolean,
default: true
},
cancelableByBgClick: {
type: Boolean,
default: true
},
},
emits: ['done', 'closed'],
data() {
return {
inputValue: this.input.default ? this.input.default : null
type Input = {
placeholder?: string;
default?: any;
};
},
computed: {
remainingLength(): number {
if (typeof this.inputValue !== "string") return 512;
return 512 - length(this.inputValue);
const props = withDefaults(defineProps<{
image: misskey.entities.DriveFile;
title?: string;
input: Input;
showOkButton: boolean;
showCancelButton: boolean;
cancelableByBgClick: boolean;
}>(), {
title: undefined,
showOkButton: true,
showCancelButton: true,
cancelableByBgClick: true,
});
const emit = defineEmits<{
(ev: 'done', v: { canceled: boolean, result?: string }): void,
(ev: 'closed'): void,
}>();
let inputValue: string | undefined = $ref(props.input.default ?? undefined);
let modal = $ref<InstanceType<typeof MkModal>>();
function done(canceled: boolean, result?: string): void {
emit('done', { canceled, result });
modal.close();
}
},
mounted() {
document.addEventListener('keydown', this.onKeydown);
},
async function ok(): Promise<void> {
if (!props.showOkButton) return;
beforeUnmount() {
document.removeEventListener('keydown', this.onKeydown);
},
methods: {
bytes,
number,
done(canceled, result?) {
this.$emit('done', { canceled, result });
this.$refs.modal.close();
},
async ok() {
if (!this.showOkButton) return;
const result = this.inputValue;
this.done(false, result);
},
cancel() {
this.done(true);
},
onBgClick() {
if (this.cancelableByBgClick) {
this.cancel();
const result = inputValue;
done(false, result);
}
},
onKeydown(evt) {
if (evt.which === 27) { // ESC
this.cancel();
function cancel(): void {
done(true);
}
},
onInputKeydown(evt) {
if (evt.which === 13) { // Enter
function onKeydown(evt: KeyboardEvent): void {
if (evt.key === 'Escape') {
cancel();
}
}
function onInputKeydown(evt: KeyboardEvent): void {
if (evt.key === 'Enter') {
if (evt.ctrlKey) {
evt.preventDefault();
evt.stopPropagation();
this.ok();
}
ok();
}
}
}
const remainingLength = computed((): number => {
if (typeof inputValue !== 'string') return 512;
return 512 - length(inputValue);
});
onMounted(() => {
document.addEventListener('keydown', onKeydown);
});
onBeforeUnmount(() => {
document.removeEventListener('keydown', onKeydown);
});
</script>