summaryrefslogtreecommitdiff
path: root/packages/client/src/components
diff options
context:
space:
mode:
authorsyuilo <Syuilotan@yahoo.co.jp>2022-12-21 16:00:00 +0900
committersyuilo <Syuilotan@yahoo.co.jp>2022-12-21 16:00:00 +0900
commit689411c19a267630855251f7d54999250faabbf7 (patch)
tree195dc5dd4e843551e97a5500005638b052b1b12c /packages/client/src/components
parent:art: (diff)
downloadsharkey-689411c19a267630855251f7d54999250faabbf7.tar.gz
sharkey-689411c19a267630855251f7d54999250faabbf7.tar.bz2
sharkey-689411c19a267630855251f7d54999250faabbf7.zip
refactor(client): refacotr MkMediaCaption
Diffstat (limited to 'packages/client/src/components')
-rw-r--r--packages/client/src/components/MkDrive.file.vue18
-rw-r--r--packages/client/src/components/MkFileCaptionEditWindow.vue175
-rw-r--r--packages/client/src/components/MkMediaCaption.vue263
-rw-r--r--packages/client/src/components/MkPostFormAttaches.vue17
4 files changed, 187 insertions, 286 deletions
diff --git a/packages/client/src/components/MkDrive.file.vue b/packages/client/src/components/MkDrive.file.vue
index 11bd9e9e3b..8c17c0530a 100644
--- a/packages/client/src/components/MkDrive.file.vue
+++ b/packages/client/src/components/MkDrive.file.vue
@@ -71,7 +71,7 @@ function getMenu() {
action: toggleSensitive,
}, {
text: i18n.ts.describeFile,
- icon: 'ti ti-forms',
+ icon: 'ti ti-text-caption',
action: describe,
}, null, {
text: i18n.ts.copyUrl,
@@ -134,20 +134,14 @@ function rename() {
}
function describe() {
- os.popup(defineAsyncComponent(() => import('@/components/MkMediaCaption.vue')), {
- title: i18n.ts.describeFile,
- input: {
- placeholder: i18n.ts.inputNewDescription,
- default: props.file.comment != null ? props.file.comment : '',
- },
- image: props.file,
+ os.popup(defineAsyncComponent(() => import('@/components/MkFileCaptionEditWindow.vue')), {
+ default: props.file.comment != null ? props.file.comment : '',
+ file: props.file,
}, {
- done: result => {
- if (!result || result.canceled) return;
- let comment = result.result;
+ done: caption => {
os.api('drive/files/update', {
fileId: props.file.id,
- comment: comment.length === 0 ? null : comment,
+ comment: caption.length === 0 ? null : caption,
});
},
}, 'closed');
diff --git a/packages/client/src/components/MkFileCaptionEditWindow.vue b/packages/client/src/components/MkFileCaptionEditWindow.vue
new file mode 100644
index 0000000000..73875251f0
--- /dev/null
+++ b/packages/client/src/components/MkFileCaptionEditWindow.vue
@@ -0,0 +1,175 @@
+<template>
+<XModalWindow
+ ref="dialog"
+ :width="400"
+ :height="450"
+ :with-ok-button="true"
+ :ok-button-disabled="false"
+ @ok="ok()"
+ @close="dialog.close()"
+ @closed="emit('closed')"
+>
+ <template #header>{{ i18n.ts.describeFile }}</template>
+ <div>
+ <MkDriveFileThumbnail class="thumbnail" :file="file" fit="contain" style="height: 100px;"/>
+ <MkTextarea v-model="caption" autofocus :placeholder="i18n.ts.inputNewDescription">
+ <template #label>{{ i18n.ts.caption }}</template>
+ </MkTextarea>
+ </div>
+</XModalWindow>
+</template>
+
+<script lang="ts" setup>
+import { } from 'vue';
+import * as Misskey from 'misskey-js';
+import XModalWindow from '@/components/MkModalWindow.vue';
+import MkTextarea from '@/components/form/textarea.vue';
+import MkDriveFileThumbnail from '@/components/MkDriveFileThumbnail.vue';
+import { i18n } from '@/i18n';
+
+const props = defineProps<{
+ file: Misskey.entities.DriveFile;
+ default: string;
+}>();
+
+const emit = defineEmits<{
+ (ev: 'done', v: string): void;
+ (ev: 'closed'): void;
+}>();
+
+const dialog = $ref<InstanceType<typeof XModalWindow>>();
+
+let caption = $ref(props.default);
+
+async function ok() {
+ emit('done', caption);
+ dialog.close();
+}
+</script>
+
+<style lang="scss" scoped>
+.container {
+ display: flex;
+ width: 100%;
+ height: 100%;
+ flex-direction: row;
+ overflow: scroll;
+ position: fixed;
+ left: 0;
+ top: 0;
+}
+@media (max-width: 850px) {
+ .container {
+ flex-direction: column;
+ }
+ .top-caption {
+ padding-bottom: 8px;
+ }
+}
+.fullwidth {
+ width: 100%;
+ margin: auto;
+}
+.mk-dialog {
+ position: relative;
+ padding: 32px;
+ min-width: 320px;
+ max-width: 480px;
+ box-sizing: border-box;
+ text-align: center;
+ background: var(--panel);
+ border-radius: var(--radius);
+ margin: auto;
+
+ > header {
+ margin: 0 0 8px 0;
+ position: relative;
+
+ > .title {
+ font-weight: bold;
+ font-size: 20px;
+ }
+
+ > .text-count {
+ opacity: 0.7;
+ position: absolute;
+ right: 0;
+ }
+ }
+
+ > .buttons {
+ margin-top: 16px;
+
+ > * {
+ margin: 0 8px;
+ }
+ }
+
+ > textarea {
+ display: block;
+ box-sizing: border-box;
+ padding: 0 24px;
+ margin: 0;
+ width: 100%;
+ font-size: 16px;
+ border: none;
+ border-radius: 0;
+ background: transparent;
+ color: var(--fg);
+ font-family: inherit;
+ max-width: 100%;
+ min-width: 100%;
+ min-height: 90px;
+
+ &:focus-visible {
+ outline: none;
+ }
+
+ &:disabled {
+ opacity: 0.5;
+ }
+ }
+}
+.hdrwpsaf {
+ display: flex;
+ flex-direction: column;
+ height: 100%;
+
+ > header,
+ > footer {
+ align-self: center;
+ display: inline-block;
+ padding: 6px 9px;
+ font-size: 90%;
+ background: rgba(0, 0, 0, 0.5);
+ border-radius: 6px;
+ color: #fff;
+ }
+
+ > header {
+ margin-bottom: 8px;
+ opacity: 0.9;
+ }
+
+ > img {
+ display: block;
+ flex: 1;
+ min-height: 0;
+ object-fit: contain;
+ width: 100%;
+ cursor: zoom-out;
+ image-orientation: from-image;
+ }
+
+ > footer {
+ margin-top: 8px;
+ opacity: 0.8;
+
+ > span + span {
+ margin-left: 0.5em;
+ padding-left: 0.5em;
+ border-left: solid 1px rgba(255, 255, 255, 0.5);
+ }
+ }
+}
+</style>
diff --git a/packages/client/src/components/MkMediaCaption.vue b/packages/client/src/components/MkMediaCaption.vue
deleted file mode 100644
index c25755d762..0000000000
--- a/packages/client/src/components/MkMediaCaption.vue
+++ /dev/null
@@ -1,263 +0,0 @@
-<template>
- <MkModal ref="modal" @click="done(true)" @closed="$emit('closed')">
- <div class="container">
- <div class="fullwidth top-caption">
- <div class="mk-dialog">
- <header>
- <Mfm v-if="title" class="title" :text="title"/>
- <span class="text-count" :class="{ over: remainingLength < 0 }">{{ remainingLength }}</span>
- </header>
- <textarea v-model="inputValue" autofocus :placeholder="input.placeholder" @keydown="onInputKeydown"></textarea>
- <div v-if="(showOkButton || showCancelButton)" class="buttons">
- <MkButton inline primary :disabled="remainingLength < 0" @click="ok">{{ $ts.ok }}</MkButton>
- <MkButton inline @click="cancel" >{{ $ts.cancel }}</MkButton>
- </div>
- </div>
- </div>
- <div class="hdrwpsaf fullwidth">
- <header>{{ image.name }}</header>
- <img :src="image.url" :alt="image.comment" :title="image.comment" @click="$refs.modal.close()"/>
- <footer>
- <span>{{ image.type }}</span>
- <span>{{ bytes(image.size) }}</span>
- <span v-if="image.properties && image.properties.width">{{ number(image.properties.width) }}px × {{ number(image.properties.height) }}px</span>
- </footer>
- </div>
- </div>
- </MkModal>
-</template>
-
-<script lang="ts">
-import { defineComponent } from 'vue';
-import { length } from 'stringz';
-import MkModal from '@/components/MkModal.vue';
-import MkButton from '@/components/MkButton.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
- };
- },
-
- computed: {
- remainingLength(): number {
- if (typeof this.inputValue !== "string") return 512;
- return 512 - length(this.inputValue);
- }
- },
-
- mounted() {
- document.addEventListener('keydown', this.onKeydown);
- },
-
- 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();
- }
- },
-
- onKeydown(evt) {
- if (evt.which === 27) { // ESC
- this.cancel();
- }
- },
-
- onInputKeydown(evt) {
- if (evt.which === 13) { // Enter
- if (evt.ctrlKey) {
- evt.preventDefault();
- evt.stopPropagation();
- this.ok();
- }
- }
- }
- }
-});
-</script>
-
-<style lang="scss" scoped>
-.container {
- display: flex;
- width: 100%;
- height: 100%;
- flex-direction: row;
- overflow: scroll;
- position: fixed;
- left: 0;
- top: 0;
-}
-@media (max-width: 850px) {
- .container {
- flex-direction: column;
- }
- .top-caption {
- padding-bottom: 8px;
- }
-}
-.fullwidth {
- width: 100%;
- margin: auto;
-}
-.mk-dialog {
- position: relative;
- padding: 32px;
- min-width: 320px;
- max-width: 480px;
- box-sizing: border-box;
- text-align: center;
- background: var(--panel);
- border-radius: var(--radius);
- margin: auto;
-
- > header {
- margin: 0 0 8px 0;
- position: relative;
-
- > .title {
- font-weight: bold;
- font-size: 20px;
- }
-
- > .text-count {
- opacity: 0.7;
- position: absolute;
- right: 0;
- }
- }
-
- > .buttons {
- margin-top: 16px;
-
- > * {
- margin: 0 8px;
- }
- }
-
- > textarea {
- display: block;
- box-sizing: border-box;
- padding: 0 24px;
- margin: 0;
- width: 100%;
- font-size: 16px;
- border: none;
- border-radius: 0;
- background: transparent;
- color: var(--fg);
- font-family: inherit;
- max-width: 100%;
- min-width: 100%;
- min-height: 90px;
-
- &:focus-visible {
- outline: none;
- }
-
- &:disabled {
- opacity: 0.5;
- }
- }
-}
-.hdrwpsaf {
- display: flex;
- flex-direction: column;
- height: 100%;
-
- > header,
- > footer {
- align-self: center;
- display: inline-block;
- padding: 6px 9px;
- font-size: 90%;
- background: rgba(0, 0, 0, 0.5);
- border-radius: 6px;
- color: #fff;
- }
-
- > header {
- margin-bottom: 8px;
- opacity: 0.9;
- }
-
- > img {
- display: block;
- flex: 1;
- min-height: 0;
- object-fit: contain;
- width: 100%;
- cursor: zoom-out;
- image-orientation: from-image;
- }
-
- > footer {
- margin-top: 8px;
- opacity: 0.8;
-
- > span + span {
- margin-left: 0.5em;
- padding-left: 0.5em;
- border-left: solid 1px rgba(255, 255, 255, 0.5);
- }
- }
-}
-</style>
diff --git a/packages/client/src/components/MkPostFormAttaches.vue b/packages/client/src/components/MkPostFormAttaches.vue
index 955d835f25..2e16cc52a7 100644
--- a/packages/client/src/components/MkPostFormAttaches.vue
+++ b/packages/client/src/components/MkPostFormAttaches.vue
@@ -70,17 +70,12 @@ async function rename(file) {
}
async function describe(file) {
- os.popup(defineAsyncComponent(() => import('@/components/MkMediaCaption.vue')), {
- title: i18n.ts.describeFile,
- input: {
- placeholder: i18n.ts.inputNewDescription,
- default: file.comment !== null ? file.comment : '',
- },
- image: file,
+ os.popup(defineAsyncComponent(() => import('@/components/MkFileCaptionEditWindow.vue')), {
+ default: file.comment !== null ? file.comment : '',
+ file: file,
}, {
- done: result => {
- if (!result || result.canceled) return;
- let comment = result.result.length === 0 ? null : result.result;
+ done: caption => {
+ let comment = caption.length === 0 ? null : caption;
os.api('drive/files/update', {
fileId: file.id,
comment: comment,
@@ -103,7 +98,7 @@ function showFileMenu(file, ev: MouseEvent) {
action: () => { toggleSensitive(file); },
}, {
text: i18n.ts.describeFile,
- icon: 'ti ti-forms',
+ icon: 'ti ti-text-caption',
action: () => { describe(file); },
}, {
text: i18n.ts.attachCancel,