diff options
| author | syuilo <Syuilotan@yahoo.co.jp> | 2021-05-04 22:53:25 +0900 |
|---|---|---|
| committer | syuilo <Syuilotan@yahoo.co.jp> | 2021-05-04 22:53:25 +0900 |
| commit | cdef5cd1ad7c1195d0273f6d78fc6aafe990007b (patch) | |
| tree | 621bb32c52de5ca1b153c3d3fbe3573919fe0205 /src/client/components | |
| parent | Merge branch 'develop' (diff) | |
| parent | 12.80.0 (diff) | |
| download | misskey-cdef5cd1ad7c1195d0273f6d78fc6aafe990007b.tar.gz misskey-cdef5cd1ad7c1195d0273f6d78fc6aafe990007b.tar.bz2 misskey-cdef5cd1ad7c1195d0273f6d78fc6aafe990007b.zip | |
Merge branch 'develop'
Diffstat (limited to 'src/client/components')
| -rw-r--r-- | src/client/components/date-separated-list.vue | 22 | ||||
| -rw-r--r-- | src/client/components/emoji-picker.vue | 3 | ||||
| -rw-r--r-- | src/client/components/forgot-password.vue | 71 | ||||
| -rw-r--r-- | src/client/components/global/ad.vue | 142 | ||||
| -rw-r--r-- | src/client/components/global/url.vue | 2 | ||||
| -rw-r--r-- | src/client/components/index.ts | 4 | ||||
| -rw-r--r-- | src/client/components/note-preview.vue | 13 | ||||
| -rw-r--r-- | src/client/components/notes.vue | 2 | ||||
| -rwxr-xr-x | src/client/components/signin.vue | 10 |
9 files changed, 250 insertions, 19 deletions
diff --git a/src/client/components/date-separated-list.vue b/src/client/components/date-separated-list.vue index 2a861adb09..d458a0eeb8 100644 --- a/src/client/components/date-separated-list.vue +++ b/src/client/components/date-separated-list.vue @@ -1,5 +1,6 @@ <script lang="ts"> import { defineComponent, h, TransitionGroup } from 'vue'; +import MkAd from '@client/components/global/ad.vue'; export default defineComponent({ props: { @@ -22,6 +23,11 @@ export default defineComponent({ required: false, default: false }, + ad: { + type: Boolean, + required: false, + default: false + }, }, methods: { @@ -58,11 +64,7 @@ export default defineComponent({ if ( i != this.items.length - 1 && - new Date(item.createdAt).getDate() != new Date(this.items[i + 1].createdAt).getDate() && - !item._prId_ && - !this.items[i + 1]._prId_ && - !item._featuredId_ && - !this.items[i + 1]._featuredId_ + new Date(item.createdAt).getDate() != new Date(this.items[i + 1].createdAt).getDate() ) { const separator = h('div', { class: 'separator', @@ -86,7 +88,15 @@ export default defineComponent({ return [el, separator]; } else { - return el; + if (this.ad && item._shouldInsertAd_) { + return [h(MkAd, { + class: 'ad', + key: item.id + ':ad', + prefer: 'horizontal', + }), el]; + } else { + return el; + } } })); }, diff --git a/src/client/components/emoji-picker.vue b/src/client/components/emoji-picker.vue index 9bec319af2..06653324d7 100644 --- a/src/client/components/emoji-picker.vue +++ b/src/client/components/emoji-picker.vue @@ -35,6 +35,7 @@ class="_button" @click="chosen(emoji, $event)" tabindex="0" + :key="emoji" > <MkEmoji :emoji="emoji" :normal="true"/> </button> @@ -104,7 +105,7 @@ export default defineComponent({ return { emojilist: markRaw(emojilist), getStaticImageUrl, - pinned: this.$store.state.reactions, + pinned: this.$store.reactiveState.reactions, width: this.asReactionPicker ? this.$store.state.reactionPickerWidth : 3, height: this.asReactionPicker ? this.$store.state.reactionPickerHeight : 2, big: this.asReactionPicker ? isDeviceTouch : false, diff --git a/src/client/components/forgot-password.vue b/src/client/components/forgot-password.vue new file mode 100644 index 0000000000..1f530d7ca2 --- /dev/null +++ b/src/client/components/forgot-password.vue @@ -0,0 +1,71 @@ +<template> +<XModalWindow ref="dialog" + :width="370" + :height="400" + @close="$refs.dialog.close()" + @closed="$emit('closed')" +> + <template #header>{{ $ts.forgotPassword }}</template> + + <form class="_monolithic_" @submit.prevent="onSubmit" v-if="$instance.enableEmail"> + <div class="_section"> + <MkInput v-model:value="username" type="text" pattern="^[a-zA-Z0-9_]+$" spellcheck="false" autofocus required> + <span>{{ $ts.username }}</span> + <template #prefix>@</template> + </MkInput> + + <MkInput v-model:value="email" type="email" spellcheck="false" required> + <span>{{ $ts.emailAddress }}</span> + <template #desc>{{ $ts._forgotPassword.enterEmail }}</template> + </MkInput> + + <MkButton type="submit" :disabled="processing" primary style="margin: 0 auto;">{{ $ts.send }}</MkButton> + </div> + <div class="_section"> + <MkA to="/about" class="_link">{{ $ts._forgotPassword.ifNoEmail }}</MkA> + </div> + </form> + <div v-else> + {{ $ts._forgotPassword.contactAdmin }} + </div> +</XModalWindow> +</template> + +<script lang="ts"> +import { defineComponent } from 'vue'; +import XModalWindow from '@client/components/ui/modal-window.vue'; +import MkButton from '@client/components/ui/button.vue'; +import MkInput from '@client/components/ui/input.vue'; +import * as os from '@client/os'; + +export default defineComponent({ + components: { + XModalWindow, + MkButton, + MkInput, + }, + + emits: ['done', 'closed'], + + data() { + return { + username: '', + email: '', + processing: false, + }; + }, + + methods: { + async onSubmit() { + this.processing = true; + await os.apiWithDialog('request-reset-password', { + username: this.username, + email: this.email, + }); + + this.$emit('done'); + this.$refs.dialog.close(); + } + } +}); +</script> diff --git a/src/client/components/global/ad.vue b/src/client/components/global/ad.vue new file mode 100644 index 0000000000..00592e4ca2 --- /dev/null +++ b/src/client/components/global/ad.vue @@ -0,0 +1,142 @@ +<template> +<div class="qiivuoyo" v-if="ad"> + <div class="main" :class="ad.place" v-if="!showMenu"> + <a :href="ad.url" target="_blank"> + <img :src="ad.imageUrl"> + <button class="_button menu" @click.prevent.stop="toggleMenu"><span class="fas fa-info-circle"></span></button> + </a> + </div> + <div class="menu" v-else> + <div class="body"> + <div>Ads by {{ host }}</div> + <!--<MkButton>{{ $ts.stopThisAd }}</MkButton>--> + <button class="_textButton" @click="toggleMenu">{{ $ts.close }}</button> + </div> + </div> +</div> +</template> + +<script lang="ts"> +import { defineComponent, ref } from 'vue'; +import { instance } from '@client/instance'; +import { host } from '@client/config'; +import MkButton from '@client/components/ui/button.vue'; + +export default defineComponent({ + components: { + MkButton + }, + + props: { + prefer: { + type: String, + required: true + }, + ad: { + type: Object, + required: false + }, + }, + + setup(props) { + const showMenu = ref(false); + const toggleMenu = () => { + showMenu.value = !showMenu.value; + }; + + let ad = null; + + if (props.ad) { + ad = props.ad; + } else { + let ads = instance.ads.filter(ad => ad.place === props.prefer); + + if (ads.length === 0) { + ads = instance.ads.filter(ad => ad.place === 'square'); + } + + const high = ads.filter(ad => ad.priority === 'high'); + const middle = ads.filter(ad => ad.priority === 'middle'); + const low = ads.filter(ad => ad.priority === 'low'); + + if (high.length > 0) { + ad = high[Math.floor(Math.random() * high.length)]; + } else if (middle.length > 0) { + ad = middle[Math.floor(Math.random() * middle.length)]; + } else if (low.length > 0) { + ad = low[Math.floor(Math.random() * low.length)]; + } + } + + return { + ad, + showMenu, + toggleMenu, + host, + }; + } +}); +</script> + +<style lang="scss" scoped> +.qiivuoyo { + background-size: auto auto; + background-image: repeating-linear-gradient(45deg, transparent, transparent 8px, var(--ad) 8px, var(--ad) 14px ); + + > .main { + > a { + display: block; + position: relative; + margin: 0 auto; + + > img { + display: block; + width: 100%; + height: 100%; + object-fit: contain; + } + + > .menu { + position: absolute; + top: 0; + right: 0; + background: var(--panel); + } + } + + &.square { + > a { + max-width: min(300px, 100%); + max-height: min(300px, 100%); + } + } + + &.horizontal { + padding: 8px; + + > a { + max-width: min(600px, 100%); + max-height: min(100px, 100%); + } + } + + &.vertical { + > a { + max-width: min(100px, 100%); + } + } + } + + > .menu { + padding: 8px; + text-align: center; + + > .body { + padding: 8px; + margin: 0 auto; + max-width: 400px; + border: solid 1px var(--divider); + } + } +} +</style> diff --git a/src/client/components/global/url.vue b/src/client/components/global/url.vue index e633a57bd8..218729882d 100644 --- a/src/client/components/global/url.vue +++ b/src/client/components/global/url.vue @@ -113,8 +113,6 @@ export default defineComponent({ > .icon { padding-left: 2px; font-size: .9em; - font-weight: 400; - font-style: normal; } > .self { diff --git a/src/client/components/index.ts b/src/client/components/index.ts index 0630ed3d8c..8b914c5eec 100644 --- a/src/client/components/index.ts +++ b/src/client/components/index.ts @@ -12,8 +12,10 @@ import url from './global/url.vue'; import i18n from './global/i18n'; import loading from './global/loading.vue'; import error from './global/error.vue'; +import ad from './global/ad.vue'; export default function(app: App) { + app.component('I18n', i18n); app.component('Mfm', mfm); app.component('MkA', a); app.component('MkAcct', acct); @@ -25,5 +27,5 @@ export default function(app: App) { app.component('MkUrl', url); app.component('MkLoading', loading); app.component('MkError', error); - app.component('I18n', i18n); + app.component('MkAd', ad); } diff --git a/src/client/components/note-preview.vue b/src/client/components/note-preview.vue index fcae4c4368..4248c2bb1d 100644 --- a/src/client/components/note-preview.vue +++ b/src/client/components/note-preview.vue @@ -1,5 +1,5 @@ <template> -<div class="yohlumlk"> +<div class="yohlumlk" v-size="{ min: [350, 500] }"> <MkAvatar class="avatar" :user="note.user"/> <div class="main"> <XNoteHeader class="header" :note="note" :mini="true"/> @@ -50,18 +50,19 @@ export default defineComponent({ display: flex; margin: 0; padding: 0; - overflow: hidden; + overflow: clip; font-size: 0.95em; - > .avatar { - - @media (min-width: 350px) { + &.min-width_350px { + > .avatar { margin: 0 10px 0 0; width: 44px; height: 44px; } + } - @media (min-width: 500px) { + &.min-width_500px { + > .avatar { margin: 0 12px 0 0; width: 48px; height: 48px; diff --git a/src/client/components/notes.vue b/src/client/components/notes.vue index 675748d540..e90102921a 100644 --- a/src/client/components/notes.vue +++ b/src/client/components/notes.vue @@ -17,7 +17,7 @@ </MkButton> </div> - <XList ref="notes" :items="notes" v-slot="{ item: note }" :direction="reversed ? 'up' : 'down'" :reversed="reversed" :no-gap="noGap"> + <XList ref="notes" :items="notes" v-slot="{ item: note }" :direction="reversed ? 'up' : 'down'" :reversed="reversed" :no-gap="noGap" :ad="true"> <XNote :note="note" class="_block" @update:note="updated(note, $event)" :key="note._featuredId_ || note._prId_ || note.id"/> </XList> diff --git a/src/client/components/signin.vue b/src/client/components/signin.vue index 2c883e0c32..f8249ffcd6 100755 --- a/src/client/components/signin.vue +++ b/src/client/components/signin.vue @@ -11,6 +11,7 @@ <MkInput v-model:value="password" type="password" :with-password-toggle="true" v-if="!user || user && !user.usePasswordLessLogin" required> <span>{{ $ts.password }}</span> <template #prefix><i class="fas fa-lock"></i></template> + <template #desc><button class="_textButton" @click="resetPassword">{{ $ts.forgotPassword }}</button></template> </MkInput> <MkButton type="submit" primary :disabled="signing" style="margin: 0 auto;">{{ signing ? $ts.loggingIn : $ts.login }}</MkButton> </div> @@ -49,8 +50,8 @@ <script lang="ts"> import { defineComponent } from 'vue'; import { toUnicode } from 'punycode/'; -import MkButton from './ui/button.vue'; -import MkInput from './ui/input.vue'; +import MkButton from '@client/components/ui/button.vue'; +import MkInput from '@client/components/ui/input.vue'; import { apiUrl, host } from '@client/config'; import { byteify, hexify } from '@client/scripts/2fa'; import * as os from '@client/os'; @@ -197,6 +198,11 @@ export default defineComponent({ this.signing = false; }); } + }, + + resetPassword() { + os.popup(import('@client/components/forgot-password.vue'), {}, { + }, 'closed'); } } }); |