Merge branch 'develop' into math-block

This commit is contained in:
Aya Morisawa
2019-01-27 16:41:30 +09:00
committed by GitHub
48 changed files with 791 additions and 852 deletions

View File

@ -0,0 +1,82 @@
<template>
<div class="kofvwchc">
<div>
<a :href="user | userPage(null, true)">
<mk-avatar class="avatar" :user="user" :disable-link="true"/>
</a>
</div>
<div>
<header>
<b><mk-user-name :user="user"/></b>
<span class="username">@{{ user | acct }}</span>
<span class="is-admin" v-if="user.isAdmin">admin</span>
<span class="is-moderator" v-if="user.isModerator">moderator</span>
<span class="is-verified" v-if="user.isVerified" :title="$t('@.verified-user')"><fa icon="star"/></span>
<span class="is-suspended" v-if="user.isSuspended" :title="$t('@.suspended-user')"><fa :icon="faSnowflake"/></span>
</header>
<div>
<span>{{ $t('users.updatedAt') }}: <mk-time :time="user.updatedAt" mode="detail"/></span>
</div>
<div>
<span>{{ $t('users.createdAt') }}: <mk-time :time="user.createdAt" mode="detail"/></span>
</div>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../i18n';
import { faSnowflake } from '@fortawesome/free-regular-svg-icons';
export default Vue.extend({
i18n: i18n('admin/views/users.vue'),
props: ['user'],
data() {
return {
faSnowflake
};
},
});
</script>
<style lang="stylus" scoped>
.kofvwchc
display flex
padding 16px 0
border-top solid 1px var(--faceDivider)
> div:first-child
> a
> .avatar
width 64px
height 64px
> div:last-child
flex 1
padding-left 16px
@media (max-width 500px)
font-size 14px
> header
> .username
margin-left 8px
opacity 0.7
> .is-admin
> .is-moderator
flex-shrink 0
align-self center
margin 0 0 0 .5em
padding 1px 6px
font-size 80%
border-radius 3px
background var(--noteHeaderAdminBg)
color var(--noteHeaderAdminFg)
> .is-verified
> .is-suspended
margin 0 0 0 .5em
color #4dabf7
</style>

View File

@ -3,20 +3,27 @@
<ui-card>
<div slot="title"><fa :icon="faTerminal"/> {{ $t('operation') }}</div>
<section class="fit-top">
<ui-input v-model="target" type="text">
<ui-input class="target" v-model="target" type="text">
<span>{{ $t('username-or-userid') }}</span>
</ui-input>
<ui-button @click="resetPassword"><fa :icon="faKey"/> {{ $t('reset-password') }}</ui-button>
<ui-horizon-group>
<ui-button @click="verifyUser" :disabled="verifying"><fa :icon="faCertificate"/> {{ $t('verify') }}</ui-button>
<ui-button @click="unverifyUser" :disabled="unverifying">{{ $t('unverify') }}</ui-button>
</ui-horizon-group>
<ui-horizon-group>
<ui-button @click="suspendUser" :disabled="suspending"><fa :icon="faSnowflake"/> {{ $t('suspend') }}</ui-button>
<ui-button @click="unsuspendUser" :disabled="unsuspending">{{ $t('unsuspend') }}</ui-button>
</ui-horizon-group>
<ui-button @click="showUser"><fa :icon="faSearch"/> {{ $t('lookup') }}</ui-button>
<ui-textarea v-if="user" :value="user | json5" readonly tall style="margin-top:16px;"></ui-textarea>
<div class="user" v-if="user">
<x-user :user='user'/>
<div class="actions">
<ui-button @click="resetPassword"><fa :icon="faKey"/> {{ $t('reset-password') }}</ui-button>
<ui-horizon-group>
<ui-button @click="verifyUser" :disabled="verifying"><fa :icon="faCertificate"/> {{ $t('verify') }}</ui-button>
<ui-button @click="unverifyUser" :disabled="unverifying">{{ $t('unverify') }}</ui-button>
</ui-horizon-group>
<ui-horizon-group>
<ui-button @click="suspendUser" :disabled="suspending"><fa :icon="faSnowflake"/> {{ $t('suspend') }}</ui-button>
<ui-button @click="unsuspendUser" :disabled="unsuspending">{{ $t('unsuspend') }}</ui-button>
</ui-horizon-group>
<ui-button v-if="user.host != null" @click="updateRemoteUser"><fa :icon="faSync"/> {{ $t('update-remote-user') }}</ui-button>
<ui-textarea v-if="user" :value="user | json5" readonly tall style="margin-top:16px;"></ui-textarea>
</div>
</div>
</section>
</ui-card>
@ -47,29 +54,7 @@
</ui-select>
</ui-horizon-group>
<sequential-entrance animation="entranceFromTop" delay="25">
<div class="kofvwchc" v-for="user in users" :key="user.id">
<div>
<a :href="user | userPage(null, true)">
<mk-avatar class="avatar" :user="user" :disable-link="true"/>
</a>
</div>
<div>
<header>
<b><mk-user-name :user="user"/></b>
<span class="username">@{{ user | acct }}</span>
<span class="is-admin" v-if="user.isAdmin">admin</span>
<span class="is-moderator" v-if="user.isModerator">moderator</span>
<span class="is-verified" v-if="user.isVerified" :title="$t('@.verified-user')"><fa icon="star"/></span>
<span class="is-suspended" v-if="user.isSuspended" :title="$t('@.suspended-user')"><fa :icon="faSnowflake"/></span>
</header>
<div>
<span>{{ $t('users.updatedAt') }}: <mk-time :time="user.updatedAt" mode="detail"/></span>
</div>
<div>
<span>{{ $t('users.createdAt') }}: <mk-time :time="user.createdAt" mode="detail"/></span>
</div>
</div>
</div>
<x-user v-for="user in users" :user='user' :key="user.id"/>
</sequential-entrance>
<ui-button v-if="existMore" @click="fetchUsers">{{ $t('@.load-more') }}</ui-button>
</section>
@ -81,12 +66,15 @@
import Vue from 'vue';
import i18n from '../../i18n';
import parseAcct from "../../../../misc/acct/parse";
import { faCertificate, faUsers, faTerminal, faSearch, faKey } from '@fortawesome/free-solid-svg-icons';
import { faCertificate, faUsers, faTerminal, faSearch, faKey, faSync } from '@fortawesome/free-solid-svg-icons';
import { faSnowflake } from '@fortawesome/free-regular-svg-icons';
import XUser from './users.user.vue';
export default Vue.extend({
i18n: i18n('admin/views/users.vue'),
components: {
XUser
},
data() {
return {
user: null,
@ -102,7 +90,7 @@ export default Vue.extend({
offset: 0,
users: [],
existMore: false,
faTerminal, faCertificate, faUsers, faSnowflake, faSearch, faKey
faTerminal, faCertificate, faUsers, faSnowflake, faSearch, faKey, faSync
};
},
@ -131,6 +119,7 @@ export default Vue.extend({
},
methods: {
/** テキストエリアのユーザーを解決する */
async fetchUser() {
try {
return await this.$root.api('users/show', this.target.startsWith('@') ? parseAcct(this.target) : { userId: this.target });
@ -149,16 +138,27 @@ export default Vue.extend({
}
},
/** テキストエリアから処理対象ユーザーを設定する */
async showUser() {
this.user = null;
const user = await this.fetchUser();
this.$root.api('admin/show-user', { userId: user.id }).then(info => {
this.user = info;
});
this.target = '';
},
/** 処理対象ユーザーの情報を更新する */
async refreshUser() {
this.$root.api('admin/show-user', { userId: this.user._id }).then(info => {
this.user = info;
});
},
async resetPassword() {
const user = await this.fetchUser();
this.$root.api('admin/reset-password', { userId: user.id }).then(res => {
if (!await this.getConfirmed(this.$t('reset-password-confirm'))) return;
this.$root.api('admin/reset-password', { userId: this.user._id }).then(res => {
this.$root.dialog({
type: 'success',
text: this.$t('password-updated', { password: res.password })
@ -167,11 +167,12 @@ export default Vue.extend({
},
async verifyUser() {
if (!await this.getConfirmed(this.$t('verify-confirm'))) return;
this.verifying = true;
const process = async () => {
const user = await this.fetchUser();
await this.$root.api('admin/verify-user', { userId: user.id });
await this.$root.api('admin/verify-user', { userId: this.user._id });
this.$root.dialog({
type: 'success',
text: this.$t('verified')
@ -186,14 +187,17 @@ export default Vue.extend({
});
this.verifying = false;
this.refreshUser();
},
async unverifyUser() {
if (!await this.getConfirmed(this.$t('unverify-confirm'))) return;
this.unverifying = true;
const process = async () => {
const user = await this.fetchUser();
await this.$root.api('admin/unverify-user', { userId: user.id });
await this.$root.api('admin/unverify-user', { userId: this.user._id });
this.$root.dialog({
type: 'success',
text: this.$t('unverified')
@ -208,14 +212,17 @@ export default Vue.extend({
});
this.unverifying = false;
this.refreshUser();
},
async suspendUser() {
if (!await this.getConfirmed(this.$t('suspend-confirm'))) return;
this.suspending = true;
const process = async () => {
const user = await this.fetchUser();
await this.$root.api('admin/suspend-user', { userId: user.id });
await this.$root.api('admin/suspend-user', { userId: this.user._id });
this.$root.dialog({
type: 'success',
text: this.$t('suspended')
@ -230,14 +237,17 @@ export default Vue.extend({
});
this.suspending = false;
this.refreshUser();
},
async unsuspendUser() {
if (!await this.getConfirmed(this.$t('unsuspend-confirm'))) return;
this.unsuspending = true;
const process = async () => {
const user = await this.fetchUser();
await this.$root.api('admin/unsuspend-user', { userId: user.id });
await this.$root.api('admin/unsuspend-user', { userId: this.user._id });
this.$root.dialog({
type: 'success',
text: this.$t('unsuspended')
@ -252,8 +262,32 @@ export default Vue.extend({
});
this.unsuspending = false;
this.refreshUser();
},
async updateRemoteUser() {
this.$root.api('admin/update-remote-user', { userId: this.user._id }).then(res => {
this.$root.dialog({
type: 'success',
text: this.$t('remote-user-updated')
});
});
this.refreshUser();
},
async getConfirmed(text: string): Promise<Boolean> {
const confirm = await this.$root.dialog({
type: 'warning',
showCancelButton: true,
title: 'confirm',
text,
});
return !confirm.canceled;
}
fetchUsers() {
this.$root.api('admin/show-users', {
state: this.state,
@ -277,42 +311,12 @@ export default Vue.extend({
</script>
<style lang="stylus" scoped>
.kofvwchc
display flex
padding 16px 0
border-top solid 1px var(--faceDivider)
.target
margin-bottom 16px !important
> div:first-child
> a
> .avatar
width 64px
height 64px
.user
margin-top 32px
> div:last-child
flex 1
padding-left 16px
@media (max-width 500px)
font-size 14px
> header
> .username
margin-left 8px
opacity 0.7
> .is-admin
> .is-moderator
flex-shrink 0
align-self center
margin 0 0 0 .5em
padding 1px 6px
font-size 80%
border-radius 3px
background var(--noteHeaderAdminBg)
color var(--noteHeaderAdminFg)
> .is-verified
> .is-suspended
margin 0 0 0 .5em
color #4dabf7
> .actions
margin-left 80px
</style>

View File

@ -26,3 +26,8 @@
transform: translateY(0);
}
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}

View File

@ -72,47 +72,6 @@ body
code
font-family Consolas, 'Courier New', Courier, Monaco, monospace
.comment
opacity 0.5
.string
color #e96900
.regexp
color #e9003f
.keyword
color #2973b7
&.true
&.false
&.null
&.nil
&.undefined
color #ae81ff
.symbol
color #42b983
.number
.nan
color #ae81ff
.var:not(.keyword)
font-weight bold
font-style italic
//text-decoration underline
.method
font-style italic
color #8964c1
.property
color #a71d5d
.label
color #e9003f
pre
display block

View File

@ -133,6 +133,7 @@ export default prop => ({
case 'deleted': {
Vue.set(this.$_ns_target, 'deletedAt', body.deletedAt);
Vue.set(this.$_ns_target, 'renote', null);
this.$_ns_target.text = null;
this.$_ns_target.tags = [];
this.$_ns_target.fileIds = [];

View File

@ -0,0 +1,30 @@
<template>
<prism :inline="inline" :language="lang">{{ code }}</prism>
</template>
<script lang="ts">
import Vue from 'vue';
import 'prismjs';
import 'prismjs/themes/prism.css';
import Prism from 'vue-prism-component';
export default Vue.extend({
components: {
Prism
},
props: {
code: {
type: String,
required: true
},
lang: {
type: String,
required: false
},
inline: {
type: Boolean,
required: false
}
}
});
</script>

View File

@ -0,0 +1,28 @@
<template>
<x-code :code="code" :lang="lang" :inline="inline"/>
</template>
<script lang="ts">
import Vue from 'vue';
export default Vue.extend({
components: {
XCode: () => import('./code-core.vue').then(m => m.default)
},
props: {
code: {
type: String,
required: true
},
lang: {
type: String,
required: false
},
inline: {
type: Boolean,
required: false
}
}
});
</script>

View File

@ -5,16 +5,21 @@
<span>{{ $t('click-to-show') }}</span>
</div>
</div>
<a class="gqnyydlzavusgskkfvwvjiattxdzsqlf" v-else :href="image.url" target="_blank" :style="style" :title="image.name" @click.prevent="onClick"></a>
<a class="gqnyydlzavusgskkfvwvjiattxdzsqlf" v-else
:href="image.url"
:style="style"
:title="image.name"
@click.prevent="onClick"
></a>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../i18n';
import ImageViewer from '../../../common/views/components/image-viewer.vue';
import ImageViewer from './image-viewer.vue';
export default Vue.extend({
i18n: i18n('mobile/views/components/media-image.vue'),
i18n: i18n('common/views/components/media-image.vue'),
props: {
image: {
type: Object,
@ -58,6 +63,7 @@ export default Vue.extend({
<style lang="stylus" scoped>
.gqnyydlzavusgskkfvwvjiattxdzsqlf
display block
cursor zoom-in
overflow hidden
width 100%
height 100%

View File

@ -7,7 +7,7 @@
<div :data-count="mediaList.filter(media => previewable(media)).length" ref="grid">
<template v-for="media in mediaList">
<mk-media-video :video="media" :key="media.id" v-if="media.type.startsWith('video')"/>
<mk-media-image :image="media" :key="media.id" v-else-if="media.type.startsWith('image')" :raw="raw"/>
<x-image :image="media" :key="media.id" v-else-if="media.type.startsWith('image')" :raw="raw"/>
</template>
</div>
</div>
@ -17,10 +17,12 @@
<script lang="ts">
import Vue from 'vue';
import XBanner from './media-banner.vue';
import XImage from './media-image.vue';
export default Vue.extend({
components: {
XBanner
XBanner,
XImage
},
props: {
mediaList: {

View File

@ -6,8 +6,8 @@ import MkUrl from './url.vue';
import MkMention from './mention.vue';
import { concat, sum } from '../../../../../prelude/array';
import MkFormula from './formula.vue';
import MkCode from './code.vue';
import MkGoogle from './google.vue';
import syntaxHighlight from '../../../../../mfm/syntax-highlight';
import { host } from '../../../config';
import { preorderF, countNodesF } from '../../../../../prelude/tree';
@ -124,6 +124,25 @@ export default Vue.component('misskey-flavored-markdown', {
}, genEl(token.children));
}
case 'spin': {
motionCount++;
const isLong = sumTextsLength(token.children) > 5 || countNodesF(token.children) > 3;
const isMany = motionCount > 3;
return (createElement as any)('span', {
attrs: {
style: (this.$store.state.settings.disableAnimatedMfm || isLong || isMany) ? 'display: inline-block;' : 'display: inline-block; animation: spin 1.5s linear infinite;'
},
}, genEl(token.children));
}
case 'flip': {
return (createElement as any)('span', {
attrs: {
style: 'display: inline-block; transform: scaleX(-1);'
},
}, genEl(token.children));
}
case 'url': {
return [createElement(MkUrl, {
key: Math.random(),
@ -170,21 +189,22 @@ export default Vue.component('misskey-flavored-markdown', {
}
case 'blockCode': {
return [createElement('pre', {
class: 'code'
}, [
createElement('code', {
domProps: {
innerHTML: syntaxHighlight(token.node.props.code)
}
})
])];
return [createElement(MkCode, {
key: Math.random(),
props: {
code: token.node.props.code,
lang: token.node.props.lang,
}
})];
}
case 'inlineCode': {
return [createElement('code', {
domProps: {
innerHTML: syntaxHighlight(token.node.props.code)
return [createElement(MkCode, {
key: Math.random(),
props: {
code: token.node.props.code,
lang: token.node.props.lang,
inline: true
}
})];
}

View File

@ -24,34 +24,10 @@ export default Vue.extend({
background var(--mfmTitleBg)
border-radius 4px
>>> .code
margin 8px 0
>>> .quote
margin 8px
padding 6px 0 6px 12px
color var(--mfmQuote)
border-left solid 3px var(--mfmQuoteLine)
>>> code
padding 4px 8px
margin 0 0.5em
font-size 80%
color #525252
background rgba(0, 0, 0, 0.05)
border-radius 2px
>>> pre > code
padding 16px
margin 0
>>> [data-is-me]:after
content "you"
padding 0 4px
margin-left 4px
font-size 80%
color var(--primaryForeground)
background var(--primary)
border-radius 4px
</style>

View File

@ -1,21 +1,23 @@
<template>
<mk-window ref="window" is-modal width="800px" height="500px" @closed="destroyDom">
<span slot="header">
<span :class="$style.title">{{ $t('choose-prompt') }}</span>
<span :class="$style.count" v-if="multiple && files.length > 0">({{ $t('chosen-files', { count: files.length }) }})</span>
<span slot="header" class="jqiaciqv">
<span class="title">{{ $t('choose-prompt') }}</span>
<span class="count" v-if="multiple && files.length > 0">({{ $t('chosen-files', { count: files.length }) }})</span>
</span>
<x-drive
ref="browser"
:class="$style.browser"
:multiple="multiple"
@selected="onSelected"
@change-selection="onChangeSelection"
/>
<div :class="$style.footer">
<button :class="$style.upload" :title="$t('title')" @click="upload"><fa icon="upload"/></button>
<button :class="$style.cancel" @click="cancel">{{ $t('cancel') }}</button>
<button :class="$style.ok" :disabled="multiple && files.length == 0" @click="ok">{{ $t('ok') }}</button>
<div class="rqsvbumu">
<x-drive
ref="browser"
class="browser"
:multiple="multiple"
@selected="onSelected"
@change-selection="onChangeSelection"
/>
<div class="footer">
<button class="upload" :title="$t('title')" @click="upload"><fa icon="upload"/></button>
<ui-button inline @click="cancel" style="margin-right:16px;">{{ $t('cancel') }}</ui-button>
<ui-button inline primary :disabled="multiple && files.length == 0" @click="ok">{{ $t('ok') }}</ui-button>
</div>
</div>
</mk-window>
</template>
@ -60,120 +62,67 @@ export default Vue.extend({
});
</script>
<style lang="stylus" module>
.title
> [data-icon]
margin-right 4px
<style lang="stylus" scoped>
.jqiaciqv
.title
> [data-icon]
margin-right 4px
.count
margin-left 8px
opacity 0.7
.browser
height calc(100% - 72px)
.footer
height 72px
background var(--primaryLighten95)
.upload
display inline-block
position absolute
top 8px
left 16px
cursor pointer
padding 0
margin 8px 4px 0 0
width 40px
height 40px
font-size 1em
color var(--primaryAlpha05)
background transparent
outline none
border solid 1px transparent
border-radius 4px
&:hover
background transparent
border-color var(--primaryAlpha03)
&:active
color var(--primaryAlpha06)
background transparent
border-color var(--primaryAlpha05)
//box-shadow 0 2px 4px rgba(var(--primaryDarken50), 0.15) inset
&:focus
&:after
content ""
pointer-events none
position absolute
top -5px
right -5px
bottom -5px
left -5px
border 2px solid var(--primaryAlpha03)
border-radius 8px
.ok
.cancel
display block
position absolute
bottom 16px
cursor pointer
padding 0
margin 0
width 120px
height 40px
font-size 1em
outline none
border-radius 4px
&:focus
&:after
content ""
pointer-events none
position absolute
top -5px
right -5px
bottom -5px
left -5px
border 2px solid var(--primaryAlpha03)
border-radius 8px
&:disabled
.count
margin-left 8px
opacity 0.7
cursor default
.ok
right 16px
color var(--primaryForeground)
background linear-gradient(to bottom, var(--primaryLighten25) 0%, var(--primaryLighten10) 100%)
border solid 1px var(--primaryLighten15)
.rqsvbumu
display flex
flex-direction column
height 100%
&:not(:disabled)
font-weight bold
.browser
flex 1
overflow auto
&:hover:not(:disabled)
background linear-gradient(to bottom, var(--primaryLighten8) 0%, var(--primaryDarken8) 100%)
border-color var(--primary)
.footer
padding 16px
background var(--desktopPostFormBg)
text-align right
&:active:not(:disabled)
background var(--primary)
border-color var(--primary)
.upload
display inline-block
position absolute
top 8px
left 16px
cursor pointer
padding 0
margin 8px 4px 0 0
width 40px
height 40px
font-size 1em
color var(--primaryAlpha05)
background transparent
outline none
border solid 1px transparent
border-radius 4px
.cancel
right 148px
color #888
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
border solid 1px #e2e2e2
&:hover
background transparent
border-color var(--primaryAlpha03)
&:hover
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
border-color #dcdcdc
&:active
color var(--primaryAlpha06)
background transparent
border-color var(--primaryAlpha05)
//box-shadow 0 2px 4px rgba(var(--primaryDarken50), 0.15) inset
&:active
background #ececec
border-color #dcdcdc
&:focus
&:after
content ""
pointer-events none
position absolute
top -5px
right -5px
bottom -5px
left -5px
border 2px solid var(--primaryAlpha03)
border-radius 8px
</style>

View File

@ -1,17 +1,19 @@
<template>
<mk-window ref="window" is-modal width="800px" height="500px" @closed="destroyDom">
<span slot="header">
<span :class="$style.title">{{ $t('choose-prompt') }}</span>
<span>{{ $t('choose-prompt') }}</span>
</span>
<x-drive
ref="browser"
:class="$style.browser"
:multiple="false"
/>
<div :class="$style.footer">
<button :class="$style.cancel" @click="cancel">{{ $t('cancel') }}</button>
<button :class="$style.ok" @click="ok">{{ $t('ok') }}</button>
<div class="hllkpxxu">
<x-drive
ref="browser"
class="browser"
:multiple="false"
/>
<div class="footer">
<ui-button inline @click="cancel" style="margin-right:16px;">{{ $t('cancel') }}</ui-button>
<ui-button inline @click="ok" primary>{{ $t('ok') }}</ui-button>
</div>
</div>
</mk-window>
</template>
@ -36,79 +38,19 @@ export default Vue.extend({
});
</script>
<style lang="stylus" module>
<style lang="stylus" scoped>
.hllkpxxu
display flex
flex-direction column
height 100%
.browser
flex 1
overflow auto
.title
> [data-icon]
margin-right 4px
.browser
height calc(100% - 72px)
.footer
height 72px
background var(--primaryLighten95)
.ok
.cancel
display block
position absolute
bottom 16px
cursor pointer
padding 0
margin 0
width 120px
height 40px
font-size 1em
outline none
border-radius 4px
&:focus
&:after
content ""
pointer-events none
position absolute
top -5px
right -5px
bottom -5px
left -5px
border 2px solid var(--primaryAlpha03)
border-radius 8px
&:disabled
opacity 0.7
cursor default
.ok
right 16px
color var(--primaryForeground)
background linear-gradient(to bottom, var(--primaryLighten25) 0%, var(--primaryLighten10) 100%)
border solid 1px var(--primaryLighten15)
&:not(:disabled)
font-weight bold
&:hover:not(:disabled)
background linear-gradient(to bottom, var(--primaryLighten8) 0%, var(--primaryDarken8) 100%)
border-color var(--primary)
&:active:not(:disabled)
background var(--primary)
border-color var(--primary)
.cancel
right 148px
color #888
background linear-gradient(to bottom, #ffffff 0%, #f5f5f5 100%)
border solid 1px #e2e2e2
&:hover
background linear-gradient(to bottom, #f9f9f9 0%, #ececec 100%)
border-color #dcdcdc
&:active
background #ececec
border-color #dcdcdc
.footer
padding 16px
background var(--desktopPostFormBg)
text-align right
</style>

View File

@ -9,7 +9,6 @@ import subNoteContent from './sub-note-content.vue';
import window from './window.vue';
import noteFormWindow from './post-form-window.vue';
import renoteFormWindow from './renote-form-window.vue';
import mediaImage from './media-image.vue';
import mediaVideo from './media-video.vue';
import notifications from './notifications.vue';
import noteForm from './post-form.vue';
@ -32,7 +31,6 @@ Vue.component('mk-sub-note-content', subNoteContent);
Vue.component('mk-window', window);
Vue.component('mk-post-form-window', noteFormWindow);
Vue.component('mk-renote-form-window', renoteFormWindow);
Vue.component('mk-media-image', mediaImage);
Vue.component('mk-media-video', mediaVideo);
Vue.component('mk-notifications', notifications);
Vue.component('mk-post-form', noteForm);

View File

@ -1,81 +0,0 @@
<template>
<div class="ldwbgwstjsdgcjruamauqdrffetqudry" v-if="image.isSensitive && hide && !$store.state.device.alwaysShowNsfw" @click="hide = false">
<div>
<b><fa icon="exclamation-triangle"/> {{ $t('sensitive') }}</b>
<span>{{ $t('click-to-show') }}</span>
</div>
</div>
<a class="lcjomzwbohoelkxsnuqjiaccdbdfiazy" v-else
:href="image.url"
@click.prevent="onClick"
:style="style"
:title="image.name"
></a>
</template>
<script lang="ts">
import Vue from 'vue';
import i18n from '../../../i18n';
import ImageViewer from '../../../common/views/components/image-viewer.vue';
export default Vue.extend({
i18n: i18n('desktop/views/components/media-image.vue'),
props: {
image: {
type: Object,
required: true
},
raw: {
default: false
}
},
data() {
return {
hide: true
};
},
computed: {
style(): any {
return {
'background-color': this.image.properties.avgColor && this.image.properties.avgColor.length == 3 ? `rgb(${this.image.properties.avgColor.join(',')})` : 'transparent',
'background-image': this.raw ? `url(${this.image.url})` : `url(${this.image.thumbnailUrl})`
};
}
},
methods: {
onClick() {
this.$root.new(ImageViewer, {
image: this.image
});
}
}
});
</script>
<style lang="stylus" scoped>
.lcjomzwbohoelkxsnuqjiaccdbdfiazy
display block
cursor zoom-in
overflow hidden
width 100%
height 100%
background-position center
background-size contain
background-repeat no-repeat
.ldwbgwstjsdgcjruamauqdrffetqudry
display flex
justify-content center
align-items center
background #111
color #fff
> div
display table-cell
text-align center
font-size 12px
> *
display block
</style>

View File

@ -3,7 +3,6 @@ import Vue from 'vue';
import ui from './ui.vue';
import note from './note.vue';
import notes from './notes.vue';
import mediaImage from './media-image.vue';
import mediaVideo from './media-video.vue';
import notePreview from './note-preview.vue';
import subNoteContent from './sub-note-content.vue';
@ -24,7 +23,6 @@ import postForm from './post-form.vue';
Vue.component('mk-ui', ui);
Vue.component('mk-note', note);
Vue.component('mk-notes', notes);
Vue.component('mk-media-image', mediaImage);
Vue.component('mk-media-video', mediaVideo);
Vue.component('mk-note-preview', notePreview);
Vue.component('mk-sub-note-content', subNoteContent);