diff --git a/packages/client/src/components/MkTokenGenerateWindow.vue b/packages/client/src/components/MkTokenGenerateWindow.vue index bf5775d4d..789218a8c 100644 --- a/packages/client/src/components/MkTokenGenerateWindow.vue +++ b/packages/client/src/components/MkTokenGenerateWindow.vue @@ -1,11 +1,12 @@ <template> -<XModalWindow ref="dialog" +<XModalWindow + ref="dialog" :width="400" :height="450" :with-ok-button="true" :ok-button-disabled="false" :can-close="false" - @close="$refs.dialog.close()" + @close="dialog.close()" @closed="$emit('closed')" @ok="ok()" > @@ -27,91 +28,63 @@ </XModalWindow> </template> -<script lang="ts"> -import { defineComponent } from 'vue'; -import { permissions } from 'misskey-js'; -import XModalWindow from '@/components/ui/modal-window.vue'; +<script lang="ts" setup> +import { } from 'vue'; +import { permissions as kinds } from 'misskey-js'; import MkInput from './form/input.vue'; -import MkTextarea from './form/textarea.vue'; import MkSwitch from './form/switch.vue'; import MkButton from './ui/button.vue'; import MkInfo from './ui/info.vue'; +import XModalWindow from '@/components/ui/modal-window.vue'; -export default defineComponent({ - components: { - XModalWindow, - MkInput, - MkTextarea, - MkSwitch, - MkButton, - MkInfo, - }, - - props: { - title: { - type: String, - required: false, - default: null - }, - information: { - type: String, - required: false, - default: null - }, - initialName: { - type: String, - required: false, - default: null - }, - initialPermissions: { - type: Array, - required: false, - default: null - } - }, - - emits: ['done', 'closed'], - - data() { - return { - name: this.initialName, - permissions: {}, - kinds: permissions - }; - }, - - created() { - if (this.initialPermissions) { - for (const kind of this.initialPermissions) { - this.permissions[kind] = true; - } - } else { - for (const kind of this.kinds) { - this.permissions[kind] = false; - } - } - }, - - methods: { - ok() { - this.$emit('done', { - name: this.name, - permissions: Object.keys(this.permissions).filter(p => this.permissions[p]) - }); - this.$refs.dialog.close(); - }, - - disableAll() { - for (const p in this.permissions) { - this.permissions[p] = false; - } - }, - - enableAll() { - for (const p in this.permissions) { - this.permissions[p] = true; - } - } - } +const props = withDefaults(defineProps<{ + title?: string | null; + information?: string | null; + initialName?: string | null; + initialPermissions?: string[] | null; +}>(), { + title: null, + information: null, + initialName: null, + initialPermissions: null, }); + +const emit = defineEmits<{ + (ev: 'closed'): void; + (ev: 'done', result: { name: string | null, permissions: string[] }): void; +}>(); + +const dialog = $ref<InstanceType<typeof XModalWindow>>(); +let name = $ref(props.initialName); +let permissions = $ref({}); + +if (props.initialPermissions) { + for (const kind of props.initialPermissions) { + permissions[kind] = true; + } +} else { + for (const kind of kinds) { + permissions[kind] = false; + } +} + +function ok(): void { + emit('done', { + name: name, + permissions: Object.keys(permissions).filter(p => permissions[p]), + }); + dialog.close(); +} + +function disableAll(): void { + for (const p in permissions) { + permissions[p] = false; + } +} + +function enableAll(): void { + for (const p in permissions) { + permissions[p] = true; + } +} </script> diff --git a/packages/client/src/components/MkUrlPreviewPopup.vue b/packages/client/src/components/MkUrlPreviewPopup.vue index 2f0ffaa38..f343c6d8a 100644 --- a/packages/client/src/components/MkUrlPreviewPopup.vue +++ b/packages/client/src/components/MkUrlPreviewPopup.vue @@ -1,52 +1,37 @@ <template> <div class="fgmtyycl" :style="{ zIndex, top: top + 'px', left: left + 'px' }"> - <transition :name="$store.state.animation ? 'zoom' : ''" @after-leave="$emit('closed')"> + <transition :name="$store.state.animation ? 'zoom' : ''" @after-leave="emit('closed')"> <MkUrlPreview v-if="showing" class="_popup _shadow" :url="url"/> </transition> </div> </template> -<script lang="ts"> -import { defineComponent } from 'vue'; +<script lang="ts" setup> +import { onMounted } from 'vue'; import MkUrlPreview from '@/components/MkUrlPreview.vue'; import * as os from '@/os'; -export default defineComponent({ - components: { - MkUrlPreview, - }, +const props = defineProps<{ + showing: boolean; + url: string; + source: HTMLElement; +}>(); - props: { - url: { - type: String, - required: true, - }, - source: { - required: true, - }, - showing: { - type: Boolean, - required: true, - }, - }, +const emit = defineEmits<{ + (ev: 'closed'): void; +}>(); - data() { - return { - u: null, - top: 0, - left: 0, - zIndex: os.claimZIndex('middle'), - }; - }, +const zIndex = os.claimZIndex('middle'); +let top = $ref(0); +let left = $ref(0); - mounted() { - const rect = this.source.getBoundingClientRect(); - const x = Math.max((rect.left + (this.source.offsetWidth / 2)) - (300 / 2), 6) + window.pageXOffset; - const y = rect.top + this.source.offsetHeight + window.pageYOffset; +onMounted(() => { + const rect = props.source.getBoundingClientRect(); + const x = Math.max((rect.left + (props.source.offsetWidth / 2)) - (300 / 2), 6) + window.pageXOffset; + const y = rect.top + props.source.offsetHeight + window.pageYOffset; - this.top = y; - this.left = x; - }, + top = y; + left = x; }); </script> diff --git a/packages/client/src/components/MkUserPreview.vue b/packages/client/src/components/MkUserPreview.vue index b8a67028f..46c54e551 100644 --- a/packages/client/src/components/MkUserPreview.vue +++ b/packages/client/src/components/MkUserPreview.vue @@ -1,7 +1,7 @@ <template> -<transition :name="$store.state.animation ? 'popup' : ''" appear @after-leave="$emit('closed')"> - <div v-if="showing" class="fxxzrfni _popup _shadow" :style="{ zIndex, top: top + 'px', left: left + 'px' }" @mouseover="() => { $emit('mouseover'); }" @mouseleave="() => { $emit('mouseleave'); }"> - <div v-if="fetched" class="info"> +<transition :name="$store.state.animation ? 'popup' : ''" appear @after-leave="emit('closed')"> + <div v-if="showing" class="fxxzrfni _popup _shadow" :style="{ zIndex, top: top + 'px', left: left + 'px' }" @mouseover="() => { emit('mouseover'); }" @mouseleave="() => { emit('mouseleave'); }"> + <div v-if="user != null" class="info"> <div class="banner" :style="user.bannerUrl ? `background-image: url(${user.bannerUrl})` : ''"> <span v-if="$i && $i.id != user.id && user.isFollowed" class="followed">{{ $ts.followsYou }}</span> </div> @@ -33,71 +33,51 @@ </transition> </template> -<script lang="ts"> -import { defineComponent } from 'vue'; +<script lang="ts" setup> +import { onMounted } from 'vue'; import * as Acct from 'misskey-js/built/acct'; +import * as misskey from 'misskey-js'; import MkFollowButton from '@/components/MkFollowButton.vue'; import { userPage } from '@/filters/user'; import * as os from '@/os'; -export default defineComponent({ - components: { - MkFollowButton, - }, +const props = defineProps<{ + showing: boolean; + q: string; + source: HTMLElement; +}>(); - props: { - showing: { - type: Boolean, - required: true, - }, - q: { - type: String, - required: true, - }, - source: { - required: true, - }, - }, +const emit = defineEmits<{ + (ev: 'closed'): void; + (ev: 'mouseover'): void; + (ev: 'mouseleave'): void; +}>(); - emits: ['closed', 'mouseover', 'mouseleave'], +const zIndex = os.claimZIndex('middle'); +let user = $ref<misskey.entities.UserDetailed | null>(null); +let top = $ref(0); +let left = $ref(0); - data() { - return { - user: null, - fetched: false, - top: 0, - left: 0, - zIndex: os.claimZIndex('middle'), - }; - }, +onMounted(() => { + if (typeof props.q === 'object') { + user = props.q; + } else { + const query = props.q.startsWith('@') ? + Acct.parse(props.q.substr(1)) : + { userId: props.q }; - mounted() { - if (typeof this.q === 'object') { - this.user = this.q; - this.fetched = true; - } else { - const query = this.q.startsWith('@') ? - Acct.parse(this.q.substr(1)) : - { userId: this.q }; + os.api('users/show', query).then(res => { + if (!props.showing) return; + user = res; + }); + } - os.api('users/show', query).then(user => { - if (!this.showing) return; - this.user = user; - this.fetched = true; - }); - } + const rect = props.source.getBoundingClientRect(); + const x = ((rect.left + (props.source.offsetWidth / 2)) - (300 / 2)) + window.pageXOffset; + const y = rect.top + props.source.offsetHeight + window.pageYOffset; - const rect = this.source.getBoundingClientRect(); - const x = ((rect.left + (this.source.offsetWidth / 2)) - (300 / 2)) + window.pageXOffset; - const y = rect.top + this.source.offsetHeight + window.pageYOffset; - - this.top = y; - this.left = x; - }, - - methods: { - userPage, - }, + top = y; + left = x; }); </script> diff --git a/packages/client/src/components/form/slot.vue b/packages/client/src/components/form/slot.vue index d031b2eff..79ce8fe51 100644 --- a/packages/client/src/components/form/slot.vue +++ b/packages/client/src/components/form/slot.vue @@ -8,12 +8,12 @@ </div> </template> -<script lang="ts"> -import { defineComponent } from 'vue'; +<script lang="ts" setup> +import { } from 'vue'; -export default defineComponent({ - -}); +function focus() { + // TODO +} </script> <style lang="scss" scoped> diff --git a/packages/client/src/components/global/i18n.ts b/packages/client/src/components/global/i18n.ts index abf0c9685..1fd293ba1 100644 --- a/packages/client/src/components/global/i18n.ts +++ b/packages/client/src/components/global/i18n.ts @@ -30,7 +30,7 @@ export default defineComponent({ } else { if (nextBracketOpen > 0) parsed.push(str.substr(0, nextBracketOpen)); parsed.push({ - arg: str.substring(nextBracketOpen + 1, nextBracketClose) + arg: str.substring(nextBracketOpen + 1, nextBracketClose), }); } @@ -38,5 +38,5 @@ export default defineComponent({ } return h(this.tag, parsed.map(x => typeof x === 'string' ? (this.textTag ? h(this.textTag, x) : x) : this.$slots[x.arg]())); - } + }, }); diff --git a/packages/client/src/pages/user/index.photos.vue b/packages/client/src/pages/user/index.photos.vue index 2a58b49f6..df733849f 100644 --- a/packages/client/src/pages/user/index.photos.vue +++ b/packages/client/src/pages/user/index.photos.vue @@ -4,12 +4,13 @@ <div class="ujigsodd"> <MkLoading v-if="fetching"/> <div v-if="!fetching && images.length > 0" class="stream"> - <MkA v-for="image in images" - :key="image.id" + <MkA + v-for="image in images" + :key="image.note.id + image.file.id" class="img" :to="notePage(image.note)" > - <ImgWithBlurhash :hash="image.blurhash" :src="thumbnail(image.file)" :alt="image.name" :title="image.name"/> + <ImgWithBlurhash :hash="image.file.blurhash" :src="thumbnail(image.file)" :title="image.file.name"/> </MkA> </div> <p v-if="!fetching && images.length == 0" class="empty">{{ $ts.nothing }}</p> @@ -17,64 +18,56 @@ </MkContainer> </template> -<script lang="ts"> -import { defineComponent } from 'vue'; +<script lang="ts" setup> +import { onMounted } from 'vue'; +import * as misskey from 'misskey-js'; import { getStaticImageUrl } from '@/scripts/get-static-image-url'; import { notePage } from '@/filters/note'; import * as os from '@/os'; import MkContainer from '@/components/ui/container.vue'; import ImgWithBlurhash from '@/components/MkImgWithBlurhash.vue'; +import { defaultStore } from '@/store'; -export default defineComponent({ - components: { - MkContainer, - ImgWithBlurhash, - }, - props: { - user: { - type: Object, - required: true - }, - }, - data() { - return { - fetching: true, - images: [], - }; - }, - mounted() { - const image = [ - 'image/jpeg', - 'image/png', - 'image/gif', - 'image/apng', - 'image/vnd.mozilla.apng', - ]; - os.api('users/notes', { - userId: this.user.id, - fileType: image, - excludeNsfw: this.$store.state.nsfw !== 'ignore', - limit: 10, - }).then(notes => { - for (const note of notes) { - for (const file of note.files) { - this.images.push({ - note, - file - }); - } +const props = defineProps<{ + user: misskey.entities.UserDetailed; +}>(); + +let fetching = $ref(true); +let images = $ref<{ + note: misskey.entities.Note; + file: misskey.entities.DriveFile; +}[]>([]); + +function thumbnail(image: misskey.entities.DriveFile): string { + return defaultStore.state.disableShowingAnimatedImages + ? getStaticImageUrl(image.thumbnailUrl) + : image.thumbnailUrl; +} + +onMounted(() => { + const image = [ + 'image/jpeg', + 'image/png', + 'image/gif', + 'image/apng', + 'image/vnd.mozilla.apng', + ]; + os.api('users/notes', { + userId: props.user.id, + fileType: image, + excludeNsfw: defaultStore.state.nsfw !== 'ignore', + limit: 10, + }).then(notes => { + for (const note of notes) { + for (const file of note.files) { + images.push({ + note, + file, + }); } - this.fetching = false; - }); - }, - methods: { - thumbnail(image: any): string { - return this.$store.state.disableShowingAnimatedImages - ? getStaticImageUrl(image.thumbnailUrl) - : image.thumbnailUrl; - }, - notePage - }, + } + fetching = false; + }); }); </script>