mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-27 16:53:10 +02:00
Merge branch 'develop' into dependabot/npm_and_yarn/@fortawesome/fontawesome-svg-core-1.2.12
This commit is contained in:
commit
49d9e51f72
25 changed files with 185 additions and 31 deletions
|
@ -1,6 +1,13 @@
|
||||||
ChangeLog
|
ChangeLog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
unreleased
|
||||||
|
----------
|
||||||
|
* Pleromaとのフェデレーションを修正
|
||||||
|
* インスタンスのキャラクター画像を設定できるように
|
||||||
|
* Catモードの朝鮮語対応
|
||||||
|
* CWが付いた投稿に返信する際、そのCWを引き継ぐように
|
||||||
|
|
||||||
10.73.0
|
10.73.0
|
||||||
-------
|
-------
|
||||||
* テーマの強化
|
* テーマの強化
|
||||||
|
|
|
@ -992,6 +992,7 @@ admin/views/instance.vue:
|
||||||
instance-name: "Instance name"
|
instance-name: "Instance name"
|
||||||
instance-description: "Instance description"
|
instance-description: "Instance description"
|
||||||
host: "Host"
|
host: "Host"
|
||||||
|
logo-url: "Logo image URL"
|
||||||
banner-url: "Banner image URL"
|
banner-url: "Banner image URL"
|
||||||
error-image-url: "Error image URL"
|
error-image-url: "Error image URL"
|
||||||
languages: "Language of this instance"
|
languages: "Language of this instance"
|
||||||
|
|
16
package.json
16
package.json
|
@ -21,7 +21,7 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fortawesome/fontawesome-svg-core": "1.2.12",
|
"@fortawesome/fontawesome-svg-core": "1.2.12",
|
||||||
"@fortawesome/free-brands-svg-icons": "5.6.0",
|
"@fortawesome/free-brands-svg-icons": "5.6.3",
|
||||||
"@fortawesome/free-regular-svg-icons": "5.5.0",
|
"@fortawesome/free-regular-svg-icons": "5.5.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "5.6.3",
|
"@fortawesome/free-solid-svg-icons": "5.6.3",
|
||||||
"@fortawesome/vue-fontawesome": "0.1.2",
|
"@fortawesome/vue-fontawesome": "0.1.2",
|
||||||
|
@ -34,7 +34,7 @@
|
||||||
"@types/debug": "0.0.31",
|
"@types/debug": "0.0.31",
|
||||||
"@types/deep-equal": "1.0.1",
|
"@types/deep-equal": "1.0.1",
|
||||||
"@types/double-ended-queue": "2.1.0",
|
"@types/double-ended-queue": "2.1.0",
|
||||||
"@types/elasticsearch": "5.0.29",
|
"@types/elasticsearch": "5.0.30",
|
||||||
"@types/file-type": "10.6.0",
|
"@types/file-type": "10.6.0",
|
||||||
"@types/gulp": "3.8.36",
|
"@types/gulp": "3.8.36",
|
||||||
"@types/gulp-mocha": "0.0.32",
|
"@types/gulp-mocha": "0.0.32",
|
||||||
|
@ -46,7 +46,7 @@
|
||||||
"@types/is-url": "1.2.28",
|
"@types/is-url": "1.2.28",
|
||||||
"@types/js-yaml": "3.11.4",
|
"@types/js-yaml": "3.11.4",
|
||||||
"@types/katex": "0.5.0",
|
"@types/katex": "0.5.0",
|
||||||
"@types/koa": "2.0.47",
|
"@types/koa": "2.0.48",
|
||||||
"@types/koa-bodyparser": "5.0.2",
|
"@types/koa-bodyparser": "5.0.2",
|
||||||
"@types/koa-compress": "2.0.8",
|
"@types/koa-compress": "2.0.8",
|
||||||
"@types/koa-favicon": "2.0.19",
|
"@types/koa-favicon": "2.0.19",
|
||||||
|
@ -70,7 +70,7 @@
|
||||||
"@types/pug": "2.0.4",
|
"@types/pug": "2.0.4",
|
||||||
"@types/qrcode": "1.3.0",
|
"@types/qrcode": "1.3.0",
|
||||||
"@types/ratelimiter": "2.1.28",
|
"@types/ratelimiter": "2.1.28",
|
||||||
"@types/redis": "2.8.8",
|
"@types/redis": "2.8.10",
|
||||||
"@types/request": "2.48.1",
|
"@types/request": "2.48.1",
|
||||||
"@types/request-promise-native": "1.0.15",
|
"@types/request-promise-native": "1.0.15",
|
||||||
"@types/rimraf": "2.0.2",
|
"@types/rimraf": "2.0.2",
|
||||||
|
@ -87,7 +87,7 @@
|
||||||
"@types/websocket": "0.0.40",
|
"@types/websocket": "0.0.40",
|
||||||
"@types/ws": "6.0.1",
|
"@types/ws": "6.0.1",
|
||||||
"animejs": "2.2.0",
|
"animejs": "2.2.0",
|
||||||
"apexcharts": "2.4.2",
|
"apexcharts": "2.5.1",
|
||||||
"autobind-decorator": "2.4.0",
|
"autobind-decorator": "2.4.0",
|
||||||
"autosize": "4.0.2",
|
"autosize": "4.0.2",
|
||||||
"autwh": "0.1.0",
|
"autwh": "0.1.0",
|
||||||
|
@ -116,7 +116,7 @@
|
||||||
"eventemitter3": "3.1.0",
|
"eventemitter3": "3.1.0",
|
||||||
"feed": "2.0.2",
|
"feed": "2.0.2",
|
||||||
"file-loader": "2.0.0",
|
"file-loader": "2.0.0",
|
||||||
"file-type": "10.6.0",
|
"file-type": "10.7.0",
|
||||||
"fuckadblock": "3.2.1",
|
"fuckadblock": "3.2.1",
|
||||||
"gulp": "3.9.1",
|
"gulp": "3.9.1",
|
||||||
"gulp-cssnano": "2.1.3",
|
"gulp-cssnano": "2.1.3",
|
||||||
|
@ -222,7 +222,7 @@
|
||||||
"vue-color": "2.7.0",
|
"vue-color": "2.7.0",
|
||||||
"vue-content-loading": "1.5.3",
|
"vue-content-loading": "1.5.3",
|
||||||
"vue-cropperjs": "3.0.0",
|
"vue-cropperjs": "3.0.0",
|
||||||
"vue-i18n": "8.3.2",
|
"vue-i18n": "8.6.0",
|
||||||
"vue-js-modal": "1.3.28",
|
"vue-js-modal": "1.3.28",
|
||||||
"vue-loader": "15.4.2",
|
"vue-loader": "15.4.2",
|
||||||
"vue-marquee-text-component": "1.1.0",
|
"vue-marquee-text-component": "1.1.0",
|
||||||
|
@ -237,7 +237,7 @@
|
||||||
"vuex-persistedstate": "2.5.4",
|
"vuex-persistedstate": "2.5.4",
|
||||||
"web-push": "3.3.3",
|
"web-push": "3.3.3",
|
||||||
"webfinger.js": "2.7.0",
|
"webfinger.js": "2.7.0",
|
||||||
"webpack": "4.26.1",
|
"webpack": "4.28.3",
|
||||||
"webpack-cli": "3.1.2",
|
"webpack-cli": "3.1.2",
|
||||||
"websocket": "1.0.28",
|
"websocket": "1.0.28",
|
||||||
"ws": "6.1.2",
|
"ws": "6.1.2",
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
<ui-input :value="host" readonly>{{ $t('host') }}</ui-input>
|
<ui-input :value="host" readonly>{{ $t('host') }}</ui-input>
|
||||||
<ui-input v-model="name">{{ $t('instance-name') }}</ui-input>
|
<ui-input v-model="name">{{ $t('instance-name') }}</ui-input>
|
||||||
<ui-textarea v-model="description">{{ $t('instance-description') }}</ui-textarea>
|
<ui-textarea v-model="description">{{ $t('instance-description') }}</ui-textarea>
|
||||||
|
<ui-input v-model="mascotImageUrl"><i slot="icon"><fa icon="link"/></i>{{ $t('logo-url') }}</ui-input>
|
||||||
<ui-input v-model="bannerUrl"><i slot="icon"><fa icon="link"/></i>{{ $t('banner-url') }}</ui-input>
|
<ui-input v-model="bannerUrl"><i slot="icon"><fa icon="link"/></i>{{ $t('banner-url') }}</ui-input>
|
||||||
<ui-input v-model="errorImageUrl"><i slot="icon"><fa icon="link"/></i>{{ $t('error-image-url') }}</ui-input>
|
<ui-input v-model="errorImageUrl"><i slot="icon"><fa icon="link"/></i>{{ $t('error-image-url') }}</ui-input>
|
||||||
<ui-input v-model="languages"><i slot="icon"><fa icon="language"/></i>{{ $t('languages') }}<span slot="desc">{{ $t('languages-desc') }}</span></ui-input>
|
<ui-input v-model="languages"><i slot="icon"><fa icon="language"/></i>{{ $t('languages') }}<span slot="desc">{{ $t('languages-desc') }}</span></ui-input>
|
||||||
|
@ -149,6 +150,7 @@ export default Vue.extend({
|
||||||
maintainerEmail: null,
|
maintainerEmail: null,
|
||||||
disableRegistration: false,
|
disableRegistration: false,
|
||||||
disableLocalTimeline: false,
|
disableLocalTimeline: false,
|
||||||
|
mascotImageUrl: null,
|
||||||
bannerUrl: null,
|
bannerUrl: null,
|
||||||
errorImageUrl: null,
|
errorImageUrl: null,
|
||||||
name: null,
|
name: null,
|
||||||
|
@ -196,6 +198,7 @@ export default Vue.extend({
|
||||||
this.maintainerEmail = meta.maintainer.email;
|
this.maintainerEmail = meta.maintainer.email;
|
||||||
this.disableRegistration = meta.disableRegistration;
|
this.disableRegistration = meta.disableRegistration;
|
||||||
this.disableLocalTimeline = meta.disableLocalTimeline;
|
this.disableLocalTimeline = meta.disableLocalTimeline;
|
||||||
|
this.mascotImageUrl = meta.mascotImageUrl;
|
||||||
this.bannerUrl = meta.bannerUrl;
|
this.bannerUrl = meta.bannerUrl;
|
||||||
this.errorImageUrl = meta.errorImageUrl;
|
this.errorImageUrl = meta.errorImageUrl;
|
||||||
this.name = meta.name;
|
this.name = meta.name;
|
||||||
|
@ -253,6 +256,7 @@ export default Vue.extend({
|
||||||
maintainerEmail: this.maintainerEmail,
|
maintainerEmail: this.maintainerEmail,
|
||||||
disableRegistration: this.disableRegistration,
|
disableRegistration: this.disableRegistration,
|
||||||
disableLocalTimeline: this.disableLocalTimeline,
|
disableLocalTimeline: this.disableLocalTimeline,
|
||||||
|
mascotImageUrl: this.mascotImageUrl,
|
||||||
bannerUrl: this.bannerUrl,
|
bannerUrl: this.bannerUrl,
|
||||||
errorImageUrl: this.errorImageUrl,
|
errorImageUrl: this.errorImageUrl,
|
||||||
name: this.name,
|
name: this.name,
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
<span class="mk-acct">
|
<span class="mk-acct">
|
||||||
<span class="name">@{{ user.username }}</span>
|
<span class="name">@{{ user.username }}</span>
|
||||||
<span class="host" :class="{ fade: $store.state.settings.contrastedAcct }" v-if="user.host || detail || $store.state.settings.showFullAcct">@{{ user.host || host }}</span>
|
<span class="host" :class="{ fade: $store.state.settings.contrastedAcct }" v-if="user.host || detail || $store.state.settings.showFullAcct">@{{ user.host || host }}</span>
|
||||||
|
<fa v-if="user.isLocked == true" class="locked" icon="lock" fixed-width/>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -23,4 +24,8 @@ export default Vue.extend({
|
||||||
.mk-acct
|
.mk-acct
|
||||||
> .host.fade
|
> .host.fade
|
||||||
opacity 0.5
|
opacity 0.5
|
||||||
|
|
||||||
|
> .locked
|
||||||
|
opacity 0.8
|
||||||
|
margin-left 0.5em
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -8,16 +8,16 @@
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</div>
|
</div>
|
||||||
<div v-else class="mk-url-preview">
|
<div v-else class="mk-url-preview">
|
||||||
<a :class="{ mini }" :href="url" target="_blank" :title="url" v-if="!fetching">
|
<a :class="{ mini, compact }" :href="url" target="_blank" :title="url" v-if="!fetching">
|
||||||
<div class="thumbnail" v-if="thumbnail" :style="`background-image: url(${thumbnail})`"></div>
|
<div class="thumbnail" v-if="thumbnail" :style="`background-image: url(${thumbnail})`"></div>
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
<h1>{{ title }}</h1>
|
<h1 :title="title">{{ title }}</h1>
|
||||||
</header>
|
</header>
|
||||||
<p v-if="description">{{ description.length > 85 ? description.slice(0, 85) + '…' : description }}</p>
|
<p v-if="description" :title="description">{{ description.length > 85 ? description.slice(0, 85) + '…' : description }}</p>
|
||||||
<footer>
|
<footer>
|
||||||
<img class="icon" v-if="icon" :src="icon"/>
|
<img class="icon" v-if="icon" :src="icon"/>
|
||||||
<p>{{ sitename }}</p>
|
<p :title="sitename">{{ sitename }}</p>
|
||||||
</footer>
|
</footer>
|
||||||
</article>
|
</article>
|
||||||
</a>
|
</a>
|
||||||
|
@ -120,6 +120,12 @@ export default Vue.extend({
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
compact: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
|
||||||
mini: {
|
mini: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
|
@ -302,6 +308,23 @@ export default Vue.extend({
|
||||||
width 12px
|
width 12px
|
||||||
height 12px
|
height 12px
|
||||||
|
|
||||||
|
&.compact
|
||||||
|
> .thumbnail
|
||||||
|
position: absolute
|
||||||
|
width 56px
|
||||||
|
height 100%
|
||||||
|
|
||||||
|
> article
|
||||||
|
left 56px
|
||||||
|
width calc(100% - 56px)
|
||||||
|
padding 4px
|
||||||
|
|
||||||
|
> header
|
||||||
|
margin-bottom 2px
|
||||||
|
|
||||||
|
> footer
|
||||||
|
margin-top 2px
|
||||||
|
|
||||||
&.mini
|
&.mini
|
||||||
font-size 10px
|
font-size 10px
|
||||||
|
|
||||||
|
@ -325,4 +348,27 @@ export default Vue.extend({
|
||||||
width 12px
|
width 12px
|
||||||
height 12px
|
height 12px
|
||||||
|
|
||||||
|
&.compact
|
||||||
|
> .thumbnail
|
||||||
|
position: absolute
|
||||||
|
width 56px
|
||||||
|
height 100%
|
||||||
|
|
||||||
|
> article
|
||||||
|
left 56px
|
||||||
|
width calc(100% - 56px)
|
||||||
|
padding 4px
|
||||||
|
|
||||||
|
> header
|
||||||
|
margin-bottom 2px
|
||||||
|
|
||||||
|
> footer
|
||||||
|
margin-top 2px
|
||||||
|
|
||||||
|
&.compact
|
||||||
|
> article
|
||||||
|
> header h1, p, footer
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
<mk-poll v-if="appearNote.poll" :note="appearNote" ref="pollViewer"/>
|
<mk-poll v-if="appearNote.poll" :note="appearNote" ref="pollViewer"/>
|
||||||
<a class="location" v-if="appearNote.geo" :href="`https://maps.google.com/maps?q=${appearNote.geo.coordinates[1]},${appearNote.geo.coordinates[0]}`" target="_blank"><fa icon="map-marker-alt"/> 位置情報</a>
|
<a class="location" v-if="appearNote.geo" :href="`https://maps.google.com/maps?q=${appearNote.geo.coordinates[1]},${appearNote.geo.coordinates[0]}`" target="_blank"><fa icon="map-marker-alt"/> 位置情報</a>
|
||||||
<div class="renote" v-if="appearNote.renote"><mk-note-preview :note="appearNote.renote" :mini="mini"/></div>
|
<div class="renote" v-if="appearNote.renote"><mk-note-preview :note="appearNote.renote" :mini="mini"/></div>
|
||||||
<mk-url-preview v-for="url in urls" :url="url" :key="url" :mini="mini"/>
|
<mk-url-preview v-for="url in urls" :url="url" :key="url" :mini="mini" :compact="compact"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer v-if="appearNote.deletedAt == null">
|
<footer v-if="appearNote.deletedAt == null">
|
||||||
|
@ -102,6 +102,11 @@ export default Vue.extend({
|
||||||
required: false,
|
required: false,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
compact: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
mini: {
|
mini: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
||||||
<component :is="!$store.state.device.reduceMotion ? 'transition-group' : 'div'" name="mk-notes" class="notes transition" tag="div" ref="notes">
|
<component :is="!$store.state.device.reduceMotion ? 'transition-group' : 'div'" name="mk-notes" class="notes transition" tag="div" ref="notes">
|
||||||
<template v-for="(note, i) in _notes">
|
<template v-for="(note, i) in _notes">
|
||||||
<x-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)" ref="note"/>
|
<x-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)" :compact="true" ref="note"/>
|
||||||
<p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
|
<p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
|
||||||
<span><fa icon="angle-up"/>{{ note._datetext }}</span>
|
<span><fa icon="angle-up"/>{{ note._datetext }}</span>
|
||||||
<span><fa icon="angle-down"/>{{ _notes[i + 1]._datetext }}</span>
|
<span><fa icon="angle-down"/>{{ _notes[i + 1]._datetext }}</span>
|
||||||
|
|
|
@ -77,6 +77,7 @@ import extractMentions from '../../../../../misc/extract-mentions';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
i18n: i18n('desktop/views/components/post-form.vue'),
|
i18n: i18n('desktop/views/components/post-form.vue'),
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
XDraggable,
|
XDraggable,
|
||||||
MkVisibilityChooser
|
MkVisibilityChooser
|
||||||
|
@ -197,11 +198,11 @@ export default Vue.extend({
|
||||||
const mention = x.host ? `@${x.username}@${toASCII(x.host)}` : `@${x.username}`;
|
const mention = x.host ? `@${x.username}@${toASCII(x.host)}` : `@${x.username}`;
|
||||||
|
|
||||||
// 自分は除外
|
// 自分は除外
|
||||||
if (this.$store.state.i.username == x.username && x.host == null) return;
|
if (this.$store.state.i.username == x.username && x.host == null) continue;
|
||||||
if (this.$store.state.i.username == x.username && x.host == host) return;
|
if (this.$store.state.i.username == x.username && x.host == host) continue;
|
||||||
|
|
||||||
// 重複は除外
|
// 重複は除外
|
||||||
if (this.text.indexOf(`${mention} `) != -1) return;
|
if (this.text.indexOf(`${mention} `) != -1) continue;
|
||||||
|
|
||||||
this.text += `${mention} `;
|
this.text += `${mention} `;
|
||||||
}
|
}
|
||||||
|
@ -221,6 +222,12 @@ export default Vue.extend({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// keep cw when reply
|
||||||
|
if (this.reply && this.reply.cw != null) {
|
||||||
|
this.useCw = true;
|
||||||
|
this.cw = this.reply.cw;
|
||||||
|
}
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
// 書きかけの投稿を復元
|
// 書きかけの投稿を復元
|
||||||
if (!this.instant && !this.mention) {
|
if (!this.instant && !this.mention) {
|
||||||
|
|
|
@ -21,7 +21,14 @@ import i18n from '../../../i18n';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
i18n: i18n('desktop/views/components/renote-form.vue'),
|
i18n: i18n('desktop/views/components/renote-form.vue'),
|
||||||
props: ['note'],
|
|
||||||
|
props: {
|
||||||
|
note: {
|
||||||
|
type: Object,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
wait: false,
|
wait: false,
|
||||||
|
@ -29,6 +36,7 @@ export default Vue.extend({
|
||||||
visibility: this.$store.state.settings.defaultNoteVisibility
|
visibility: this.$store.state.settings.defaultNoteVisibility
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
ok(v: string) {
|
ok(v: string) {
|
||||||
this.wait = true;
|
this.wait = true;
|
||||||
|
@ -44,9 +52,11 @@ export default Vue.extend({
|
||||||
this.wait = false;
|
this.wait = false;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
cancel() {
|
cancel() {
|
||||||
this.$emit('canceled');
|
this.$emit('canceled');
|
||||||
},
|
},
|
||||||
|
|
||||||
onQuote() {
|
onQuote() {
|
||||||
this.quote = true;
|
this.quote = true;
|
||||||
|
|
||||||
|
@ -54,6 +64,7 @@ export default Vue.extend({
|
||||||
(this.$refs.form as any).focus();
|
(this.$refs.form as any).focus();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onChildFormPosted() {
|
onChildFormPosted() {
|
||||||
this.$emit('posted');
|
this.$emit('posted');
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
<router-link :to="user | userPage" class="name">
|
<router-link :to="user | userPage" class="name">
|
||||||
<mk-user-name :user="user"/>
|
<mk-user-name :user="user"/>
|
||||||
</router-link>
|
</router-link>
|
||||||
<span class="username">@{{ user | acct }}</span>
|
<span class="username">@{{ user | acct }} <fa v-if="user.isLocked == true" class="locked" icon="lock" fixed-width/></span>
|
||||||
|
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<misskey-flavored-markdown v-if="user.description" :text="user.description" :author="user" :i="$store.state.i" :custom-emojis="user.emojis"/>
|
<misskey-flavored-markdown v-if="user.description" :text="user.description" :author="user" :i="$store.state.i" :custom-emojis="user.emojis"/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -75,6 +76,9 @@ export default Vue.extend({
|
||||||
display block
|
display block
|
||||||
opacity 0.7
|
opacity 0.7
|
||||||
|
|
||||||
|
> .locked
|
||||||
|
opacity 0.8
|
||||||
|
|
||||||
> .description
|
> .description
|
||||||
margin 8px 0 16px 0
|
margin 8px 0 16px 0
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
:key="note.id"
|
:key="note.id"
|
||||||
@update:note="onNoteUpdated(i, $event)"
|
@update:note="onNoteUpdated(i, $event)"
|
||||||
:media-view="mediaView"
|
:media-view="mediaView"
|
||||||
|
:compact="true"
|
||||||
:mini="true"/>
|
:mini="true"/>
|
||||||
<p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
|
<p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
|
||||||
<span><fa icon="angle-up"/>{{ note._datetext }}</span>
|
<span><fa icon="angle-up"/>{{ note._datetext }}</span>
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
<span class="name">
|
<span class="name">
|
||||||
<mk-user-name :user="user"/>
|
<mk-user-name :user="user"/>
|
||||||
</span>
|
</span>
|
||||||
<span class="acct">@{{ user | acct }}</span>
|
<span class="acct">@{{ user | acct }} <fa v-if="user.isLocked == true" class="locked" icon="lock" fixed-width/></span>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
|
@ -411,6 +411,9 @@ export default Vue.extend({
|
||||||
opacity 0.7
|
opacity 0.7
|
||||||
text-shadow 0 0 8px #000
|
text-shadow 0 0 8px #000
|
||||||
|
|
||||||
|
> .locked
|
||||||
|
opacity 0.8
|
||||||
|
|
||||||
> .info
|
> .info
|
||||||
padding 16px
|
padding 16px
|
||||||
font-size 12px
|
font-size 12px
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
<span class="signin" @click="signin">{{ $t('signin') }}</span>
|
<span class="signin" @click="signin">{{ $t('signin') }}</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<img src="/assets/ai.png" alt="" title="藍" class="char">
|
<img :src="meta.mascotImageUrl" alt="" title="藍" class="char">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
<mk-media-list :media-list="appearNote.files"/>
|
<mk-media-list :media-list="appearNote.files"/>
|
||||||
</div>
|
</div>
|
||||||
<mk-poll v-if="appearNote.poll" :note="appearNote" ref="pollViewer"/>
|
<mk-poll v-if="appearNote.poll" :note="appearNote" ref="pollViewer"/>
|
||||||
<mk-url-preview v-for="url in urls" :url="url" :key="url"/>
|
<mk-url-preview v-for="url in urls" :url="url" :key="url" :compact="compact"/>
|
||||||
<a class="location" v-if="appearNote.geo" :href="`https://maps.google.com/maps?q=${appearNote.geo.coordinates[1]},${appearNote.geo.coordinates[0]}`" target="_blank"><fa icon="map-marker-alt"/> {{ $t('location') }}</a>
|
<a class="location" v-if="appearNote.geo" :href="`https://maps.google.com/maps?q=${appearNote.geo.coordinates[1]},${appearNote.geo.coordinates[0]}`" target="_blank"><fa icon="map-marker-alt"/> {{ $t('location') }}</a>
|
||||||
<div class="renote" v-if="appearNote.renote"><mk-note-preview :note="appearNote.renote"/></div>
|
<div class="renote" v-if="appearNote.renote"><mk-note-preview :note="appearNote.renote"/></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -90,6 +90,11 @@ export default Vue.extend({
|
||||||
note: {
|
note: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
compact: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
<!-- トランジションを有効にするとなぜかメモリリークする -->
|
||||||
<component :is="!$store.state.device.reduceMotion ? 'transition-group' : 'div'" name="mk-notes" class="transition" tag="div">
|
<component :is="!$store.state.device.reduceMotion ? 'transition-group' : 'div'" name="mk-notes" class="transition" tag="div">
|
||||||
<template v-for="(note, i) in _notes">
|
<template v-for="(note, i) in _notes">
|
||||||
<mk-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)"/>
|
<mk-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)" :compact="true"/>
|
||||||
<p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
|
<p class="date" :key="note.id + '_date'" v-if="i != notes.length - 1 && note._date != _notes[i + 1]._date">
|
||||||
<span><fa icon="angle-up"/>{{ note._datetext }}</span>
|
<span><fa icon="angle-up"/>{{ note._datetext }}</span>
|
||||||
<span><fa icon="angle-down"/>{{ _notes[i + 1]._datetext }}</span>
|
<span><fa icon="angle-down"/>{{ _notes[i + 1]._datetext }}</span>
|
||||||
|
|
|
@ -187,11 +187,11 @@ export default Vue.extend({
|
||||||
const mention = x.host ? `@${x.username}@${toASCII(x.host)}` : `@${x.username}`;
|
const mention = x.host ? `@${x.username}@${toASCII(x.host)}` : `@${x.username}`;
|
||||||
|
|
||||||
// 自分は除外
|
// 自分は除外
|
||||||
if (this.$store.state.i.username == x.username && x.host == null) return;
|
if (this.$store.state.i.username == x.username && x.host == null) continue;
|
||||||
if (this.$store.state.i.username == x.username && x.host == host) return;
|
if (this.$store.state.i.username == x.username && x.host == host) continue;
|
||||||
|
|
||||||
// 重複は除外
|
// 重複は除外
|
||||||
if (this.text.indexOf(`${mention} `) != -1) return;
|
if (this.text.indexOf(`${mention} `) != -1) continue;
|
||||||
|
|
||||||
this.text += `${mention} `;
|
this.text += `${mention} `;
|
||||||
}
|
}
|
||||||
|
@ -211,6 +211,12 @@ export default Vue.extend({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// keep cw when reply
|
||||||
|
if (this.reply && this.reply.cw != null) {
|
||||||
|
this.useCw = true;
|
||||||
|
this.cw = this.reply.cw;
|
||||||
|
}
|
||||||
|
|
||||||
this.focus();
|
this.focus();
|
||||||
|
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
|
|
|
@ -19,6 +19,7 @@ const defaultMeta: any = {
|
||||||
enableExternalUserRecommendation: false,
|
enableExternalUserRecommendation: false,
|
||||||
externalUserRecommendationEngine: 'https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}',
|
externalUserRecommendationEngine: 'https://vinayaka.distsn.org/cgi-bin/vinayaka-user-match-misskey-api.cgi?{{host}}+{{user}}+{{limit}}+{{offset}}',
|
||||||
externalUserRecommendationTimeout: 300000,
|
externalUserRecommendationTimeout: 300000,
|
||||||
|
mascotImageUrl: '/assets/ai.png',
|
||||||
errorImageUrl: 'https://ai.misskey.xyz/aiart/yubitun.png',
|
errorImageUrl: 'https://ai.misskey.xyz/aiart/yubitun.png',
|
||||||
enableServiceWorker: false
|
enableServiceWorker: false
|
||||||
};
|
};
|
||||||
|
|
|
@ -185,6 +185,7 @@ export type IMeta = {
|
||||||
disableRegistration?: boolean;
|
disableRegistration?: boolean;
|
||||||
disableLocalTimeline?: boolean;
|
disableLocalTimeline?: boolean;
|
||||||
hidedTags?: string[];
|
hidedTags?: string[];
|
||||||
|
mascotImageUrl?: string;
|
||||||
bannerUrl?: string;
|
bannerUrl?: string;
|
||||||
errorImageUrl?: string;
|
errorImageUrl?: string;
|
||||||
|
|
||||||
|
|
|
@ -372,7 +372,14 @@ export const pack = async (
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
if (_note.user.isCat && _note.text) {
|
if (_note.user.isCat && _note.text) {
|
||||||
_note.text = _note.text.replace(/な/g, 'にゃ').replace(/ナ/g, 'ニャ').replace(/ナ/g, 'ニャ');
|
_note.text = (_note.text
|
||||||
|
// ja-JP
|
||||||
|
.replace(/な/g, 'にゃ').replace(/ナ/g, 'ニャ').replace(/ナ/g, 'ニャ')
|
||||||
|
// ko-KR
|
||||||
|
.replace(/[나-낳]/g, (match: string) => String.fromCharCode(
|
||||||
|
match.codePointAt(0) + '냐'.charCodeAt(0) - '나'.charCodeAt(0)
|
||||||
|
))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!opts.skipHide) {
|
if (!opts.skipHide) {
|
||||||
|
|
|
@ -83,7 +83,7 @@ router.get('/notes/:note', async (ctx, next) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.body = pack(await renderNote(note, false));
|
ctx.body = pack(await renderNote(note, false));
|
||||||
ctx.set('Cache-Control', 'private, max-age=0, must-revalidate');
|
ctx.set('Cache-Control', 'public, max-age=180');
|
||||||
setResponseType(ctx);
|
setResponseType(ctx);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -162,7 +162,9 @@ async function userInfo(ctx: Router.IRouterContext, user: IUser) {
|
||||||
setResponseType(ctx);
|
setResponseType(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
router.get('/users/:user', async ctx => {
|
router.get('/users/:user', async (ctx, next) => {
|
||||||
|
if (!isActivityPubReq(ctx)) return await next();
|
||||||
|
|
||||||
if (!ObjectID.isValid(ctx.params.user)) {
|
if (!ObjectID.isValid(ctx.params.user)) {
|
||||||
ctx.status = 404;
|
ctx.status = 404;
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -39,6 +39,13 @@ export const meta = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
mascotImageUrl: {
|
||||||
|
validator: $.str.optional.nullable,
|
||||||
|
desc: {
|
||||||
|
'ja-JP': 'インスタンスキャラクター画像のURL'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
bannerUrl: {
|
bannerUrl: {
|
||||||
validator: $.str.optional.nullable,
|
validator: $.str.optional.nullable,
|
||||||
desc: {
|
desc: {
|
||||||
|
@ -328,6 +335,10 @@ export default define(meta, (ps) => new Promise(async (res, rej) => {
|
||||||
set.hidedTags = ps.hidedTags;
|
set.hidedTags = ps.hidedTags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ps.mascotImageUrl !== undefined) {
|
||||||
|
set.mascotImageUrl = ps.mascotImageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
if (ps.bannerUrl !== undefined) {
|
if (ps.bannerUrl !== undefined) {
|
||||||
set.bannerUrl = ps.bannerUrl;
|
set.bannerUrl = ps.bannerUrl;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,7 @@ export default define(meta, (ps, me) => new Promise(async (res, rej) => {
|
||||||
enableRecaptcha: instance.enableRecaptcha,
|
enableRecaptcha: instance.enableRecaptcha,
|
||||||
recaptchaSiteKey: instance.recaptchaSiteKey,
|
recaptchaSiteKey: instance.recaptchaSiteKey,
|
||||||
swPublickey: instance.swPublicKey,
|
swPublickey: instance.swPublicKey,
|
||||||
|
mascotImageUrl: instance.mascotImageUrl,
|
||||||
bannerUrl: instance.bannerUrl,
|
bannerUrl: instance.bannerUrl,
|
||||||
errorImageUrl: instance.errorImageUrl,
|
errorImageUrl: instance.errorImageUrl,
|
||||||
maxNoteTextLength: instance.maxNoteTextLength,
|
maxNoteTextLength: instance.maxNoteTextLength,
|
||||||
|
|
|
@ -45,7 +45,7 @@ export default define(meta, (ps, user) => new Promise(async (res, rej) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (note.deletedAt != null) {
|
if (note.deletedAt != null) {
|
||||||
return rej('this not is already deleted');
|
return rej('this note is already deleted');
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -148,6 +148,27 @@ router.get('/@:user', async (ctx, next) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
router.get('/users/:user', async ctx => {
|
||||||
|
if (!ObjectID.isValid(ctx.params.user)) {
|
||||||
|
ctx.status = 404;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const userId = new ObjectID(ctx.params.user);
|
||||||
|
|
||||||
|
const user = await User.findOne({
|
||||||
|
_id: userId,
|
||||||
|
host: null
|
||||||
|
});
|
||||||
|
|
||||||
|
if (user === null) {
|
||||||
|
ctx.status = 404;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.redirect(`/@${user.username}${ user.host == null ? '' : '@' + user.host}`);
|
||||||
|
});
|
||||||
|
|
||||||
// Note
|
// Note
|
||||||
router.get('/notes/:note', async ctx => {
|
router.get('/notes/:note', async ctx => {
|
||||||
if (ObjectID.isValid(ctx.params.note)) {
|
if (ObjectID.isValid(ctx.params.note)) {
|
||||||
|
@ -159,7 +180,12 @@ router.get('/notes/:note', async ctx => {
|
||||||
note: _note,
|
note: _note,
|
||||||
summary: getNoteSummary(_note)
|
summary: getNoteSummary(_note)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (['public', 'home'].includes(note.visibility)) {
|
||||||
|
ctx.set('Cache-Control', 'public, max-age=180');
|
||||||
|
} else {
|
||||||
ctx.set('Cache-Control', 'private, max-age=0, must-revalidate');
|
ctx.set('Cache-Control', 'private, max-age=0, must-revalidate');
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue