refactor: media-caption component as composition api
This commit is contained in:
parent
0ae09f2e80
commit
b64f266483
1 changed files with 85 additions and 111 deletions
|
@ -16,7 +16,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="hdrwpsaf fullwidth">
|
<div class="hdrwpsaf fullwidth">
|
||||||
<header>{{ image.name }}</header>
|
<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>
|
<footer>
|
||||||
<span>{{ image.type }}</span>
|
<span>{{ image.type }}</span>
|
||||||
<span>{{ bytes(image.size) }}</span>
|
<span>{{ bytes(image.size) }}</span>
|
||||||
|
@ -27,111 +27,85 @@
|
||||||
</MkModal>
|
</MkModal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts" setup>
|
||||||
import { defineComponent } from 'vue';
|
import { onBeforeUnmount, onMounted, computed } from 'vue';
|
||||||
import { length } from 'stringz';
|
import { length } from 'stringz';
|
||||||
|
import * as misskey from 'misskey-js';
|
||||||
import MkModal from '@/components/ui/modal.vue';
|
import MkModal from '@/components/ui/modal.vue';
|
||||||
import MkButton from '@/components/ui/button.vue';
|
import MkButton from '@/components/ui/button.vue';
|
||||||
import bytes from '@/filters/bytes';
|
import bytes from '@/filters/bytes';
|
||||||
import number from '@/filters/number';
|
import number from '@/filters/number';
|
||||||
|
|
||||||
export default defineComponent({
|
type Input = {
|
||||||
components: {
|
placeholder?: string;
|
||||||
MkModal,
|
default?: any;
|
||||||
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
|
|
||||||
};
|
};
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
const props = withDefaults(defineProps<{
|
||||||
remainingLength(): number {
|
image: misskey.entities.DriveFile;
|
||||||
if (typeof this.inputValue !== "string") return 512;
|
title?: string;
|
||||||
return 512 - length(this.inputValue);
|
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() {
|
async function ok(): Promise<void> {
|
||||||
document.addEventListener('keydown', this.onKeydown);
|
if (!props.showOkButton) return;
|
||||||
},
|
|
||||||
|
|
||||||
beforeUnmount() {
|
const result = inputValue;
|
||||||
document.removeEventListener('keydown', this.onKeydown);
|
done(false, result);
|
||||||
},
|
|
||||||
|
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
onKeydown(evt) {
|
function cancel(): void {
|
||||||
if (evt.which === 27) { // ESC
|
done(true);
|
||||||
this.cancel();
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
|
|
||||||
onInputKeydown(evt) {
|
function onKeydown(evt: KeyboardEvent): void {
|
||||||
if (evt.which === 13) { // Enter
|
if (evt.key === 'Escape') {
|
||||||
|
cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function onInputKeydown(evt: KeyboardEvent): void {
|
||||||
|
if (evt.key === 'Enter') {
|
||||||
if (evt.ctrlKey) {
|
if (evt.ctrlKey) {
|
||||||
evt.preventDefault();
|
evt.preventDefault();
|
||||||
evt.stopPropagation();
|
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>
|
</script>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue