diff options
Diffstat (limited to 'src/client/components')
| -rw-r--r-- | src/client/components/forgot-password.vue | 25 | ||||
| -rw-r--r-- | src/client/components/form/select.vue | 34 | ||||
| -rw-r--r-- | src/client/components/google.vue | 12 | ||||
| -rw-r--r-- | src/client/components/media-video.vue | 1 | ||||
| -rw-r--r-- | src/client/components/mention.vue | 65 | ||||
| -rw-r--r-- | src/client/components/note-detailed.vue | 15 | ||||
| -rw-r--r-- | src/client/components/note.vue | 15 |
7 files changed, 103 insertions, 64 deletions
diff --git a/src/client/components/forgot-password.vue b/src/client/components/forgot-password.vue index cb2380f483..7fcf9aa720 100644 --- a/src/client/components/forgot-password.vue +++ b/src/client/components/forgot-password.vue @@ -7,21 +7,21 @@ > <template #header>{{ $ts.forgotPassword }}</template> - <form class="_monolithic_" @submit.prevent="onSubmit" v-if="$instance.enableEmail"> - <div class="_section"> - <MkInput v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required> + <form class="bafeceda" @submit.prevent="onSubmit" v-if="$instance.enableEmail"> + <div class="main _formRoot"> + <MkInput class="_formBlock" v-model="username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required> <template #label>{{ $ts.username }}</template> <template #prefix>@</template> </MkInput> - <MkInput v-model="email" type="email" spellcheck="false" required> + <MkInput class="_formBlock" v-model="email" type="email" spellcheck="false" required> <template #label>{{ $ts.emailAddress }}</template> <template #caption>{{ $ts._forgotPassword.enterEmail }}</template> </MkInput> - <MkButton type="submit" :disabled="processing" primary style="margin: 0 auto;">{{ $ts.send }}</MkButton> + <MkButton class="_formBlock" type="submit" :disabled="processing" primary style="margin: 0 auto;">{{ $ts.send }}</MkButton> </div> - <div class="_section"> + <div class="sub"> <MkA to="/about" class="_link">{{ $ts._forgotPassword.ifNoEmail }}</MkA> </div> </form> @@ -69,3 +69,16 @@ export default defineComponent({ } }); </script> + +<style lang="scss" scoped> +.bafeceda { + > .main { + padding: 24px; + } + + > .sub { + border-top: solid 0.5px var(--divider); + padding: 24px; + } +} +</style> diff --git a/src/client/components/form/select.vue b/src/client/components/form/select.vue index 9efaf02697..363b3515fa 100644 --- a/src/client/components/form/select.vue +++ b/src/client/components/form/select.vue @@ -150,26 +150,26 @@ export default defineComponent({ }); }; - for (const optionOrOptgroup of options) { - if (optionOrOptgroup.type === 'optgroup') { - const optgroup = optionOrOptgroup; - menu.push({ - type: 'label', - text: optgroup.props.label, - }); - for (const option of optgroup.children) { + const scanOptions = (options: VNode[]) => { + for (const vnode of options) { + if (vnode.type === 'optgroup') { + const optgroup = vnode; + menu.push({ + type: 'label', + text: optgroup.props.label, + }); + scanOptions(optgroup.children); + } else if (Array.isArray(vnode.children)) { // 何故かフラグメントになってくることがある + const fragment = vnode; + scanOptions(fragment.children); + } else { + const option = vnode; pushOption(option); } - } else if (Array.isArray(optionOrOptgroup.children)) { // 何故かフラグメントになってくることがある - const fragment = optionOrOptgroup; - for (const option of fragment.children) { - pushOption(option); - } - } else { - const option = optionOrOptgroup; - pushOption(option); } - } + }; + + scanOptions(options); os.popupMenu(menu, container.value, { width: container.value.offsetWidth, diff --git a/src/client/components/google.vue b/src/client/components/google.vue index 6d8ae0b5bf..be724f038d 100644 --- a/src/client/components/google.vue +++ b/src/client/components/google.vue @@ -10,7 +10,12 @@ import { defineComponent } from 'vue'; import * as os from '@client/os'; export default defineComponent({ - props: ['q'], + props: { + q: { + type: String, + required: true, + } + }, data() { return { query: null, @@ -21,10 +26,7 @@ export default defineComponent({ }, methods: { search() { - const engine = this.$store.state.webSearchEngine || - 'https://www.google.com/search?q={{query}}'; - const url = engine.replace('{{query}}', this.query) - window.open(url, '_blank'); + window.open(`https://www.google.com/search?q=${this.query}`, '_blank'); } } }); diff --git a/src/client/components/media-video.vue b/src/client/components/media-video.vue index 44367ee999..4d4a551653 100644 --- a/src/client/components/media-video.vue +++ b/src/client/components/media-video.vue @@ -11,6 +11,7 @@ :title="video.name" preload="none" controls + @contextmenu.stop > <source :src="video.url" diff --git a/src/client/components/mention.vue b/src/client/components/mention.vue index 101a9020ee..da13dcdddd 100644 --- a/src/client/components/mention.vue +++ b/src/client/components/mention.vue @@ -1,13 +1,12 @@ <template> -<MkA class="ldlomzub" :class="{ isMe }" :to="url" v-user-preview="canonical" v-if="url.startsWith('/')"> - <span class="me" v-if="isMe">{{ $ts.you }}</span> +<MkA v-if="url.startsWith('/')" class="ldlomzub" :class="{ isMe }" :to="url" v-user-preview="canonical" :style="{ background: bg }"> <img class="icon" :src="`/avatar/@${username}@${host}`" alt=""> <span class="main"> <span class="username">@{{ username }}</span> <span class="host" v-if="(host != localHost) || $store.state.showFullAcct">@{{ toUnicode(host) }}</span> </span> </MkA> -<a class="ldlomzub" :href="url" target="_blank" rel="noopener" v-else> +<a v-else class="ldlomzub" :href="url" target="_blank" rel="noopener" :style="{ background: bg }"> <span class="main"> <span class="username">@{{ username }}</span> <span class="host">@{{ toUnicode(host) }}</span> @@ -17,10 +16,11 @@ <script lang="ts"> import { defineComponent } from 'vue'; -import { toUnicode } from 'punycode/'; +import * as tinycolor from 'tinycolor2'; +import { toUnicode } from 'punycode'; import { host as localHost } from '@client/config'; import { wellKnownServices } from '../../well-known-services'; -import * as os from '@client/os'; +import { $i } from '@client/account'; export default defineComponent({ props: { @@ -33,53 +33,46 @@ export default defineComponent({ required: true } }, - data() { + + setup(props) { + const canonical = props.host === localHost ? `@${props.username}` : `@${props.username}@${toUnicode(props.host)}`; + + const wellKnown = wellKnownServices.find(x => x[0] === props.host); + const url = wellKnown ? wellKnown[1](props.username) : `/${canonical}`; + + const isMe = $i && ( + `@${props.username}@${toUnicode(props.host)}` === `@${$i.username}@${toUnicode(localHost)}`.toLowerCase() + ); + + const bg = tinycolor(getComputedStyle(document.documentElement).getPropertyValue(isMe ? '--mentionMe' : '--mention')); + bg.setAlpha(0.20); + return { - localHost + localHost, + isMe, + url, + canonical, + toUnicode, + bg: bg.toRgbString(), }; }, - computed: { - url(): string { - const wellKnown = wellKnownServices.find(x => x[0] === this.host); - if (wellKnown) { - return wellKnown[1](this.username); - } else { - return `/${this.canonical}`; - } - }, - canonical(): string { - return this.host === localHost ? `@${this.username}` : `@${this.username}@${toUnicode(this.host)}`; - }, - isMe(): boolean { - return this.$i && ( - `@${this.username}@${toUnicode(this.host)}` === `@${this.$i.username}@${toUnicode(localHost)}`.toLowerCase() - ); - } - }, - methods: { - toUnicode - } }); </script> <style lang="scss" scoped> .ldlomzub { + display: inline-block; + padding: 4px 8px 4px 4px; + border-radius: 999px; color: var(--mention); &.isMe { color: var(--mentionMe); } - - > .me { - pointer-events: none; - user-select: none; - font-size: 70%; - vertical-align: top; - } > .icon { width: 1.5em; - margin: 0 0.2em; + margin: 0 0.2em 0 0; vertical-align: bottom; border-radius: 100%; } diff --git a/src/client/components/note-detailed.vue b/src/client/components/note-detailed.vue index 40b0a68c58..568a2360d1 100644 --- a/src/client/components/note-detailed.vue +++ b/src/client/components/note-detailed.vue @@ -601,6 +601,12 @@ export default defineComponent({ }); }, + toggleThreadMute(mute: boolean) { + os.apiWithDialog(mute ? 'notes/thread-muting/create' : 'notes/thread-muting/delete', { + noteId: this.appearNote.id + }); + }, + getMenu() { let menu; if (this.$i) { @@ -657,6 +663,15 @@ export default defineComponent({ text: this.$ts.watch, action: () => this.toggleWatch(true) }) : undefined, + statePromise.then(state => state.isMutedThread ? { + icon: 'fas fa-comment-slash', + text: this.$ts.unmuteThread, + action: () => this.toggleThreadMute(false) + } : { + icon: 'fas fa-comment-slash', + text: this.$ts.muteThread, + action: () => this.toggleThreadMute(true) + }), this.appearNote.userId == this.$i.id ? (this.$i.pinnedNoteIds || []).includes(this.appearNote.id) ? { icon: 'fas fa-thumbtack', text: this.$ts.unpin, diff --git a/src/client/components/note.vue b/src/client/components/note.vue index 91a3e3b87d..681e819a22 100644 --- a/src/client/components/note.vue +++ b/src/client/components/note.vue @@ -576,6 +576,12 @@ export default defineComponent({ }); }, + toggleThreadMute(mute: boolean) { + os.apiWithDialog(mute ? 'notes/thread-muting/create' : 'notes/thread-muting/delete', { + noteId: this.appearNote.id + }); + }, + getMenu() { let menu; if (this.$i) { @@ -632,6 +638,15 @@ export default defineComponent({ text: this.$ts.watch, action: () => this.toggleWatch(true) }) : undefined, + statePromise.then(state => state.isMutedThread ? { + icon: 'fas fa-comment-slash', + text: this.$ts.unmuteThread, + action: () => this.toggleThreadMute(false) + } : { + icon: 'fas fa-comment-slash', + text: this.$ts.muteThread, + action: () => this.toggleThreadMute(true) + }), this.appearNote.userId == this.$i.id ? (this.$i.pinnedNoteIds || []).includes(this.appearNote.id) ? { icon: 'fas fa-thumbtack', text: this.$ts.unpin, |