Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b6dc6c6984 | ||
|
|
517084b1fc | ||
|
|
27763e6898 | ||
|
|
57dde1da38 | ||
|
|
0bb961767c | ||
|
|
88515ce677 | ||
|
|
00562e840c | ||
|
|
b7927ba386 | ||
|
|
9c363ff045 | ||
|
|
1dbce5e3e2 | ||
|
|
361a9ca1be | ||
|
|
cde6514839 | ||
|
|
507e2f727e | ||
|
|
8028499d2b | ||
|
|
c2c79c4a87 | ||
|
|
d56f7f3390 | ||
|
|
ef70d17194 | ||
|
|
9789b9a083 | ||
|
|
e6311fdb13 | ||
|
|
2231c54dee | ||
|
|
20de9a5e35 | ||
|
|
ec3a6d7097 | ||
|
|
9d99bf5af8 | ||
|
|
52911cc9fd | ||
|
|
6f71ba376d | ||
|
|
9f439aabba | ||
|
|
33ad60b1f3 | ||
|
|
010d3f8281 |
13
CHANGELOG.md
13
CHANGELOG.md
@@ -1,6 +1,19 @@
|
|||||||
ChangeLog
|
ChangeLog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
10.90.4
|
||||||
|
----------
|
||||||
|
* url-previewでembedプレイヤー展開をオプトインにするように
|
||||||
|
* デザインの調整
|
||||||
|
* ユーザビリティの強化
|
||||||
|
|
||||||
|
10.90.3
|
||||||
|
----------
|
||||||
|
* モバイルのデッキで投稿フォームウィジェットが設置できなかった問題を修正
|
||||||
|
* ドキュメントの強化
|
||||||
|
* デザインの調整
|
||||||
|
* ユーザビリティの強化
|
||||||
|
|
||||||
10.90.2
|
10.90.2
|
||||||
----------
|
----------
|
||||||
* アカウントが削除できない問題を修正
|
* アカウントが削除できない問題を修正
|
||||||
|
|||||||
@@ -40,10 +40,10 @@ Stands for _**M**iss**k**ey_.
|
|||||||
Stands for _**S**ervice**W**orker_.
|
Stands for _**S**ervice**W**orker_.
|
||||||
|
|
||||||
### Nyaize
|
### Nyaize
|
||||||
な を にゃ にすること
|
Convert な(na) to にゃ(nya)
|
||||||
|
|
||||||
#### Denyaize
|
#### Denyaize
|
||||||
Nyaizeを解除すること
|
Revert Nyaize
|
||||||
|
|
||||||
## Code style
|
## Code style
|
||||||
### Don't use `export default`
|
### Don't use `export default`
|
||||||
@@ -59,16 +59,16 @@ export function something(foo: string): string {
|
|||||||
|
|
||||||
## Directory structure
|
## Directory structure
|
||||||
```
|
```
|
||||||
src ... ソースコード
|
src ... Source code
|
||||||
@types ... 外部ライブラリなどの型定義
|
@types ... Type definitions
|
||||||
prelude ... Misskeyに関係ないかつ副作用なし
|
prelude ... Independence utils for coding JavaScript without side effects
|
||||||
misc ... 副作用なしのユーティリティ処理
|
misc ... Independence utils for Misskey without side effects
|
||||||
service ... 副作用ありの共通処理
|
service ... Common functions with side effects
|
||||||
queue ... ジョブキューとジョブ
|
queue ... Job queues and Jobs
|
||||||
server ... Webサーバー
|
server ... Web Server
|
||||||
client ... クライアント
|
client ... Client
|
||||||
mfm ... MFM
|
mfm ... MFM
|
||||||
|
|
||||||
test ... テスト
|
test ... Test code
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ common:
|
|||||||
signin: "ログイン"
|
signin: "ログイン"
|
||||||
signup: "新規登録"
|
signup: "新規登録"
|
||||||
signout: "ログアウト"
|
signout: "ログアウト"
|
||||||
|
reload-to-apply-the-setting: "この設定を反映するにはページをリロードする必要があります。今すぐリロードしますか?"
|
||||||
|
|
||||||
got-it: "わかった"
|
got-it: "わかった"
|
||||||
customization-tips:
|
customization-tips:
|
||||||
@@ -257,6 +258,9 @@ common/views/pages/explore.vue:
|
|||||||
explore: "{host}を探索"
|
explore: "{host}を探索"
|
||||||
users-info: "現在{users}ユーザーが登録されています"
|
users-info: "現在{users}ユーザーが登録されています"
|
||||||
|
|
||||||
|
common/views/components/url-preview.vue:
|
||||||
|
enable-player: "プレイヤーを開く"
|
||||||
|
|
||||||
common/views/components/user-list.vue:
|
common/views/components/user-list.vue:
|
||||||
no-users: "ユーザーがいません"
|
no-users: "ユーザーがいません"
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "misskey",
|
"name": "misskey",
|
||||||
"author": "syuilo <i@syuilo.com>",
|
"author": "syuilo <i@syuilo.com>",
|
||||||
"version": "10.90.2",
|
"version": "10.90.4",
|
||||||
"codename": "nighthike",
|
"codename": "nighthike",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
export default function(me, settings, note) {
|
export default function(me, settings, note) {
|
||||||
const isMyNote = note.userId == me.id;
|
const isMyNote = me && (note.userId == me.id);
|
||||||
const isPureRenote = note.renoteId != null && note.text == null && note.fileIds.length == 0 && note.poll == null;
|
const isPureRenote = note.renoteId != null && note.text == null && note.fileIds.length == 0 && note.poll == null;
|
||||||
|
|
||||||
const includesMutedWords = (text: string) =>
|
const includesMutedWords = (text: string) =>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="mk-acct">
|
<span class="mk-acct" v-once>
|
||||||
<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/>
|
<fa v-if="user.isLocked == true" class="locked" icon="lock" fixed-width/>
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<span class="mk-avatar" :style="style" :class="{ cat }" :title="user | acct" v-if="disableLink && !disablePreview" v-user-preview="user.id" @click="onClick">
|
<span class="mk-avatar" :style="style" :class="{ cat }" :title="user | acct" v-if="disableLink && !disablePreview" v-user-preview="user.id" @click="onClick" v-once>
|
||||||
<span class="inner" :style="icon"></span>
|
<span class="inner" :style="icon"></span>
|
||||||
</span>
|
</span>
|
||||||
<span class="mk-avatar" :style="style" :class="{ cat }" :title="user | acct" v-else-if="disableLink && disablePreview" @click="onClick">
|
<span class="mk-avatar" :style="style" :class="{ cat }" :title="user | acct" v-else-if="disableLink && disablePreview" @click="onClick" v-once>
|
||||||
<span class="inner" :style="icon"></span>
|
<span class="inner" :style="icon"></span>
|
||||||
</span>
|
</span>
|
||||||
<router-link class="mk-avatar" :style="style" :class="{ cat }" :to="user | userPage" :title="user | acct" :target="target" v-else-if="!disableLink && !disablePreview" v-user-preview="user.id">
|
<router-link class="mk-avatar" :style="style" :class="{ cat }" :to="user | userPage" :title="user | acct" :target="target" v-else-if="!disableLink && !disablePreview" v-user-preview="user.id" v-once>
|
||||||
<span class="inner" :style="icon"></span>
|
<span class="inner" :style="icon"></span>
|
||||||
</router-link>
|
</router-link>
|
||||||
<router-link class="mk-avatar" :style="style" :class="{ cat }" :to="user | userPage" :title="user | acct" :target="target" v-else-if="!disableLink && disablePreview">
|
<router-link class="mk-avatar" :style="style" :class="{ cat }" :to="user | userPage" :title="user | acct" :target="target" v-else-if="!disableLink && disablePreview" v-once>
|
||||||
<span class="inner" :style="icon"></span>
|
<span class="inner" :style="icon"></span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
> div
|
> div
|
||||||
background-color var(--text)
|
background-color var(--text)
|
||||||
border-radius var(--round)
|
border-radius 6px
|
||||||
color var(--secondary)
|
color var(--secondary)
|
||||||
display inline-block
|
display inline-block
|
||||||
font-size 14px
|
font-size 14px
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<mfm-core v-bind="$attrs" class="havbbuyv"/>
|
<mfm-core v-bind="$attrs" class="havbbuyv" v-once/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ui-card" :class="{ shadow: $store.state.device.useShadow }">
|
<div class="ui-card" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||||
<header>
|
<header>
|
||||||
<slot name="title"></slot>
|
<slot name="title"></slot>
|
||||||
</header>
|
</header>
|
||||||
@@ -25,7 +25,9 @@ export default Vue.extend({
|
|||||||
max-width 850px
|
max-width 850px
|
||||||
color var(--faceText)
|
color var(--faceText)
|
||||||
background var(--face)
|
background var(--face)
|
||||||
border-radius var(--round)
|
|
||||||
|
&.round
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
&.shadow
|
&.shadow
|
||||||
box-shadow 0 3px 1px -2px rgba(#000, 0.2), 0 2px 2px 0 rgba(#000, 0.14), 0 1px 5px 0 rgba(#000, 0.12)
|
box-shadow 0 3px 1px -2px rgba(#000, 0.2), 0 2px 2px 0 rgba(#000, 0.14), 0 1px 5px 0 rgba(#000, 0.12)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-if="player.url" class="player" :style="`padding: ${(player.height || 0) / (player.width || 1) * 100}% 0 0`">
|
<div v-if="playerEnabled" class="player" :style="`padding: ${(player.height || 0) / (player.width || 1) * 100}% 0 0`">
|
||||||
<iframe :src="player.url" :width="player.width || '100%'" :heigth="player.height || 250" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen />
|
<iframe :src="player.url + (player.url.match(/\?/) ? '&autoplay=1&auto_play=1' : '?autoplay=1&auto_play=1')" :width="player.width || '100%'" :heigth="player.height || 250" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen />
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="tweetUrl && detail" class="twitter">
|
<div v-else-if="tweetUrl && detail" class="twitter">
|
||||||
<blockquote ref="tweet" class="twitter-tweet" :data-theme="$store.state.device.darkmode ? 'dark' : null">
|
<blockquote ref="tweet" class="twitter-tweet" :data-theme="$store.state.device.darkmode ? 'dark' : null">
|
||||||
@@ -9,7 +9,9 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-else class="mk-url-preview">
|
<div v-else class="mk-url-preview">
|
||||||
<a :class="{ mini: narrow, compact }" :href="url" target="_blank" :title="url" v-if="!fetching">
|
<a :class="{ mini: narrow, 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}')`">
|
||||||
|
<button v-if="!playerEnabled && player.url" @click.prevent="playerEnabled = true" :title="$t('enable-player')"><fa :icon="['far', 'play-circle']"/></button>
|
||||||
|
</div>
|
||||||
<article>
|
<article>
|
||||||
<header>
|
<header>
|
||||||
<h1 :title="title">{{ title }}</h1>
|
<h1 :title="title">{{ title }}</h1>
|
||||||
@@ -26,88 +28,11 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import i18n from '../../../i18n';
|
||||||
import { url as misskeyUrl } from '../../../config';
|
import { url as misskeyUrl } from '../../../config';
|
||||||
|
|
||||||
// THIS IS THE WHITELIST FOR THE EMBED PLAYER
|
|
||||||
const whiteList = [
|
|
||||||
'afreecatv.com',
|
|
||||||
'aparat.com',
|
|
||||||
'applemusic.com',
|
|
||||||
'amazon.com',
|
|
||||||
'awa.fm',
|
|
||||||
'bandcamp.com',
|
|
||||||
'bbc.co.uk',
|
|
||||||
'beatport.com',
|
|
||||||
'bilibili.com',
|
|
||||||
'boomstream.com',
|
|
||||||
'breakers.tv',
|
|
||||||
'cam4.com',
|
|
||||||
'cavelis.net',
|
|
||||||
'chaturbate.com',
|
|
||||||
'cnn.com',
|
|
||||||
'cybergame.tv',
|
|
||||||
'dailymotion.com',
|
|
||||||
'deezer.com',
|
|
||||||
'djlive.pl',
|
|
||||||
'e-onkyo.com',
|
|
||||||
'eventials.com',
|
|
||||||
'facebook.com',
|
|
||||||
'fc2.com',
|
|
||||||
'gameplank.tv',
|
|
||||||
'goodgame.ru',
|
|
||||||
'google.com',
|
|
||||||
'hardtunes.com',
|
|
||||||
'instagram.com',
|
|
||||||
'johnnylooch.com',
|
|
||||||
'kexp.org',
|
|
||||||
'lahzenegar.com',
|
|
||||||
'liveedu.tv',
|
|
||||||
'livetube.cc',
|
|
||||||
'livestream.com',
|
|
||||||
'meridix.com',
|
|
||||||
'mixcloud.com',
|
|
||||||
'mixer.com',
|
|
||||||
'mobcrush.com',
|
|
||||||
'mylive.in.th',
|
|
||||||
'myspace.com',
|
|
||||||
'netflix.com',
|
|
||||||
'newretrowave.com',
|
|
||||||
'nhk.or.jp',
|
|
||||||
'nicovideo.jp',
|
|
||||||
'nico.ms',
|
|
||||||
'noisetrade.com',
|
|
||||||
'nood.tv',
|
|
||||||
'npr.org',
|
|
||||||
'openrec.tv',
|
|
||||||
'pandora.com',
|
|
||||||
'pandora.tv',
|
|
||||||
'picarto.tv',
|
|
||||||
'pscp.tv',
|
|
||||||
'restream.io',
|
|
||||||
'reverbnation.com',
|
|
||||||
'sermonaudio.com',
|
|
||||||
'smashcast.tv',
|
|
||||||
'songkick.com',
|
|
||||||
'soundcloud.com',
|
|
||||||
'spinninrecords.com',
|
|
||||||
'spotify.com',
|
|
||||||
'stitcher.com',
|
|
||||||
'stream.me',
|
|
||||||
'switchboard.live',
|
|
||||||
'tunein.com',
|
|
||||||
'twitcasting.tv',
|
|
||||||
'twitch.tv',
|
|
||||||
'twitter.com',
|
|
||||||
'vaughnlive.tv',
|
|
||||||
'veoh.com',
|
|
||||||
'vimeo.com',
|
|
||||||
'watchpeoplecode.com',
|
|
||||||
'web.tv',
|
|
||||||
'youtube.com',
|
|
||||||
'youtu.be'
|
|
||||||
];
|
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
|
i18n: i18n('common/views/components/url-preview.vue'),
|
||||||
props: {
|
props: {
|
||||||
url: {
|
url: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -147,7 +72,8 @@ export default Vue.extend({
|
|||||||
height: null
|
height: null
|
||||||
},
|
},
|
||||||
tweetUrl: null,
|
tweetUrl: null,
|
||||||
misskeyUrl
|
playerEnabled: false,
|
||||||
|
misskeyUrl,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -188,9 +114,7 @@ export default Vue.extend({
|
|||||||
this.icon = info.icon;
|
this.icon = info.icon;
|
||||||
this.sitename = info.sitename;
|
this.sitename = info.sitename;
|
||||||
this.fetching = false;
|
this.fetching = false;
|
||||||
if (whiteList.some(x => x == url.hostname || url.hostname.endsWith(`.${x}`))) {
|
this.player = info.player;
|
||||||
this.player = info.player;
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -230,6 +154,17 @@ export default Vue.extend({
|
|||||||
height 100%
|
height 100%
|
||||||
background-position center
|
background-position center
|
||||||
background-size cover
|
background-size cover
|
||||||
|
display flex
|
||||||
|
justify-content center
|
||||||
|
align-items center
|
||||||
|
|
||||||
|
> button
|
||||||
|
font-size 3.5em
|
||||||
|
opacity: 0.7
|
||||||
|
|
||||||
|
&:hover
|
||||||
|
font-size 4em
|
||||||
|
opacity 0.9
|
||||||
|
|
||||||
& + article
|
& + article
|
||||||
left 100px
|
left 100px
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs" :class="{ naked, narrow, active, isStacked, draghover, dragging, dropready }"
|
<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs" :class="{ naked, narrow, active, isStacked, draghover, dragging, dropready, isMobile: $root.isMobile, shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }"
|
||||||
@dragover.prevent.stop="onDragover"
|
@dragover.prevent.stop="onDragover"
|
||||||
@dragleave="onDragleave"
|
@dragleave="onDragleave"
|
||||||
@drop.prevent.stop="onDrop"
|
@drop.prevent.stop="onDrop"
|
||||||
@@ -322,10 +322,14 @@ export default Vue.extend({
|
|||||||
|
|
||||||
height 100%
|
height 100%
|
||||||
background var(--face)
|
background var(--face)
|
||||||
border-radius var(--round)
|
|
||||||
box-shadow var(--shadow)
|
|
||||||
overflow hidden
|
overflow hidden
|
||||||
|
|
||||||
|
&.round
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
|
&.shadow
|
||||||
|
box-shadow 0 3px 8px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
&.draghover
|
&.draghover
|
||||||
box-shadow 0 0 0 2px var(--primaryAlpha08)
|
box-shadow 0 0 0 2px var(--primaryAlpha08)
|
||||||
|
|
||||||
@@ -366,6 +370,10 @@ export default Vue.extend({
|
|||||||
> button
|
> button
|
||||||
color var(--text)
|
color var(--text)
|
||||||
|
|
||||||
|
&.isMobile
|
||||||
|
> header
|
||||||
|
box-shadow none
|
||||||
|
|
||||||
> header
|
> header
|
||||||
display flex
|
display flex
|
||||||
z-index 2
|
z-index 2
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import wTips from './tips.vue';
|
|||||||
import wNav from './nav.vue';
|
import wNav from './nav.vue';
|
||||||
import wHashtags from './hashtags.vue';
|
import wHashtags from './hashtags.vue';
|
||||||
import wInstance from './instance.vue';
|
import wInstance from './instance.vue';
|
||||||
|
import wPostForm from './post-form.vue';
|
||||||
|
|
||||||
Vue.component('mkw-analog-clock', wAnalogClock);
|
Vue.component('mkw-analog-clock', wAnalogClock);
|
||||||
Vue.component('mkw-nav', wNav);
|
Vue.component('mkw-nav', wNav);
|
||||||
@@ -29,3 +30,4 @@ Vue.component('mkw-rss', wRss);
|
|||||||
Vue.component('mkw-version', wVersion);
|
Vue.component('mkw-version', wVersion);
|
||||||
Vue.component('mkw-hashtags', wHashtags);
|
Vue.component('mkw-hashtags', wHashtags);
|
||||||
Vue.component('mkw-instance', wInstance);
|
Vue.component('mkw-instance', wInstance);
|
||||||
|
Vue.component('mkw-post-form', wPostForm);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
ref="text"
|
ref="text"
|
||||||
v-autocomplete="{ model: 'text' }"
|
v-autocomplete="{ model: 'text' }"
|
||||||
></textarea>
|
></textarea>
|
||||||
<button class="emoji" @click="emoji" ref="emoji">
|
<button class="emoji" @click="emoji" ref="emoji" v-if="!$root.isMobile">
|
||||||
<fa :icon="['far', 'laugh']"/>
|
<fa :icon="['far', 'laugh']"/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -161,7 +161,7 @@ export default define({
|
|||||||
},
|
},
|
||||||
|
|
||||||
async emoji() {
|
async emoji() {
|
||||||
const Picker = await import('../components/emoji-picker-dialog.vue').then(m => m.default);
|
const Picker = await import('../../../desktop/views/components/emoji-picker-dialog.vue').then(m => m.default);
|
||||||
const button = this.$refs.emoji;
|
const button = this.$refs.emoji;
|
||||||
const rect = button.getBoundingClientRect();
|
const rect = button.getBoundingClientRect();
|
||||||
const vm = this.$root.new(Picker, {
|
const vm = this.$root.new(Picker, {
|
||||||
@@ -186,6 +186,9 @@ export default define({
|
|||||||
alert('Something happened');
|
alert('Something happened');
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
this.posting = false;
|
this.posting = false;
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.text.focus();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
<div class="mkw-rss--body" :data-mobile="platform == 'mobile'">
|
<div class="mkw-rss--body" :data-mobile="platform == 'mobile'">
|
||||||
<p class="fetching" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p>
|
<p class="fetching" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p>
|
||||||
<div class="feed" v-else>
|
<div class="feed" v-else>
|
||||||
<a v-for="item in items" :href="item.link" target="_blank">{{ item.title }}</a>
|
<a v-for="item in items" :href="item.link" target="_blank" :title="item.title">{{ item.title }}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ui-container>
|
</ui-container>
|
||||||
@@ -55,12 +55,18 @@ export default define({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
setting() {
|
setting() {
|
||||||
const url = window.prompt('URL', this.props.url);
|
this.$root.dialog({
|
||||||
if (url && url != '') {
|
title: 'URL',
|
||||||
|
input: {
|
||||||
|
type: 'url',
|
||||||
|
default: this.props.url
|
||||||
|
}
|
||||||
|
}).then(({ canceled, result: url }) => {
|
||||||
|
if (canceled) return;
|
||||||
this.props.url = url;
|
this.props.url = url;
|
||||||
this.save();
|
this.save();
|
||||||
this.fetch();
|
this.fetch();
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-calendar" :data-melt="design == 4 || design == 5">
|
<div class="mk-calendar" :data-melt="design == 4 || design == 5" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||||
<template v-if="design == 0 || design == 1">
|
<template v-if="design == 0 || design == 1">
|
||||||
<button @click="prev" :title="$t('prev')"><fa icon="chevron-circle-left"/></button>
|
<button @click="prev" :title="$t('prev')"><fa icon="chevron-circle-left"/></button>
|
||||||
<p class="title">{{ $t('title', { year, month }) }}</p>
|
<p class="title">{{ $t('title', { year, month }) }}</p>
|
||||||
@@ -133,10 +133,14 @@ export default Vue.extend({
|
|||||||
.mk-calendar
|
.mk-calendar
|
||||||
color var(--calendarDay)
|
color var(--calendarDay)
|
||||||
background var(--face)
|
background var(--face)
|
||||||
box-shadow var(--shadow)
|
|
||||||
border-radius var(--round)
|
|
||||||
overflow hidden
|
overflow hidden
|
||||||
|
|
||||||
|
&.round
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
|
&.shadow
|
||||||
|
box-shadow 0 3px 8px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
&[data-melt]
|
&[data-melt]
|
||||||
background transparent !important
|
background transparent !important
|
||||||
border none !important
|
border none !important
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-note-detail" :title="title" tabindex="-1">
|
<div class="mk-note-detail" :title="title" tabindex="-1" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||||
<button
|
<button
|
||||||
class="read-more"
|
class="read-more"
|
||||||
v-if="appearNote.reply && appearNote.reply.replyId && conversation.length == 0"
|
v-if="appearNote.reply && appearNote.reply.replyId && conversation.length == 0"
|
||||||
@@ -159,8 +159,15 @@ export default Vue.extend({
|
|||||||
overflow hidden
|
overflow hidden
|
||||||
text-align left
|
text-align left
|
||||||
background var(--face)
|
background var(--face)
|
||||||
box-shadow var(--shadow)
|
|
||||||
border-radius var(--round)
|
&.round
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
|
> .read-more
|
||||||
|
border-radius 6px 6px 0 0
|
||||||
|
|
||||||
|
&.shadow
|
||||||
|
box-shadow 0 3px 8px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
> .read-more
|
> .read-more
|
||||||
display block
|
display block
|
||||||
@@ -175,7 +182,6 @@ export default Vue.extend({
|
|||||||
outline none
|
outline none
|
||||||
border none
|
border none
|
||||||
border-bottom solid 1px var(--faceDivider)
|
border-bottom solid 1px var(--faceDivider)
|
||||||
border-radius var(--round) var(--round) 0 0
|
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
box-shadow 0 0 0 100px inset rgba(0, 0, 0, 0.05)
|
box-shadow 0 0 0 100px inset rgba(0, 0, 0, 0.05)
|
||||||
|
|||||||
@@ -39,30 +39,30 @@
|
|||||||
<mk-url-preview v-for="url in urls" :url="url" :key="url" :compact="compact"/>
|
<mk-url-preview v-for="url in urls" :url="url" :key="url" :compact="compact"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer v-if="appearNote.deletedAt == null">
|
<footer v-if="appearNote.deletedAt == null" class="footer">
|
||||||
<span class="app" v-if="appearNote.app && narrow && $store.state.settings.showVia">via <b>{{ appearNote.app.name }}</b></span>
|
<span class="app" v-if="appearNote.app && narrow && $store.state.settings.showVia">via <b>{{ appearNote.app.name }}</b></span>
|
||||||
<mk-reactions-viewer :note="appearNote" ref="reactionsViewer"/>
|
<mk-reactions-viewer :note="appearNote" ref="reactionsViewer"/>
|
||||||
<button class="replyButton" @click="reply()" :title="$t('reply')">
|
<button class="replyButton button" @click="reply()" :title="$t('reply')">
|
||||||
<template v-if="appearNote.reply"><fa icon="reply-all"/></template>
|
<template v-if="appearNote.reply"><fa icon="reply-all"/></template>
|
||||||
<template v-else><fa icon="reply"/></template>
|
<template v-else><fa icon="reply"/></template>
|
||||||
<p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p>
|
<p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p>
|
||||||
</button>
|
</button>
|
||||||
<button v-if="['public', 'home'].includes(appearNote.visibility)" class="renoteButton" @click="renote()" :title="$t('renote')">
|
<button v-if="['public', 'home'].includes(appearNote.visibility)" class="renoteButton button" @click="renote()" :title="$t('renote')">
|
||||||
<fa icon="retweet"/>
|
<fa icon="retweet"/>
|
||||||
<p class="count" v-if="appearNote.renoteCount > 0">{{ appearNote.renoteCount }}</p>
|
<p class="count" v-if="appearNote.renoteCount > 0">{{ appearNote.renoteCount }}</p>
|
||||||
</button>
|
</button>
|
||||||
<button v-else class="inhibitedButton">
|
<button v-else class="inhibitedButton button">
|
||||||
<fa icon="ban"/>
|
<fa icon="ban"/>
|
||||||
</button>
|
</button>
|
||||||
<button v-if="!isMyNote && appearNote.myReaction == null" class="reactionButton" @click="react()" ref="reactButton" :title="$t('add-reaction')">
|
<button v-if="!isMyNote && appearNote.myReaction == null" class="reactionButton button" @click="react()" ref="reactButton" :title="$t('add-reaction')">
|
||||||
<fa icon="plus"/>
|
<fa icon="plus"/>
|
||||||
<p class="count" v-if="Object.values(appearNote.reactionCounts).some(x => x)">{{ Object.values(appearNote.reactionCounts).reduce((a, c) => a + c, 0) }}</p>
|
<p class="count" v-if="Object.values(appearNote.reactionCounts).some(x => x)">{{ Object.values(appearNote.reactionCounts).reduce((a, c) => a + c, 0) }}</p>
|
||||||
</button>
|
</button>
|
||||||
<button v-if="!isMyNote && appearNote.myReaction != null" class="reactionButton reacted" @click="undoReact(appearNote)" ref="reactButton" :title="$t('undo-reaction')">
|
<button v-if="!isMyNote && appearNote.myReaction != null" class="reactionButton reacted button" @click="undoReact(appearNote)" ref="reactButton" :title="$t('undo-reaction')">
|
||||||
<fa icon="minus"/>
|
<fa icon="minus"/>
|
||||||
<p class="count" v-if="Object.values(appearNote.reactionCounts).some(x => x)">{{ Object.values(appearNote.reactionCounts).reduce((a, c) => a + c, 0) }}</p>
|
<p class="count" v-if="Object.values(appearNote.reactionCounts).some(x => x)">{{ Object.values(appearNote.reactionCounts).reduce((a, c) => a + c, 0) }}</p>
|
||||||
</button>
|
</button>
|
||||||
<button @click="menu()" ref="menuButton">
|
<button @click="menu()" ref="menuButton" class="button">
|
||||||
<fa icon="ellipsis-h"/>
|
<fa icon="ellipsis-h"/>
|
||||||
</button>
|
</button>
|
||||||
</footer>
|
</footer>
|
||||||
@@ -274,7 +274,7 @@ export default Vue.extend({
|
|||||||
border dashed var(--lineWidth) var(--quoteBorder)
|
border dashed var(--lineWidth) var(--quoteBorder)
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
|
|
||||||
> footer
|
> .footer
|
||||||
> .app
|
> .app
|
||||||
display block
|
display block
|
||||||
margin-top 0.5em
|
margin-top 0.5em
|
||||||
@@ -282,7 +282,7 @@ export default Vue.extend({
|
|||||||
color var(--noteHeaderInfo)
|
color var(--noteHeaderInfo)
|
||||||
font-size 0.8em
|
font-size 0.8em
|
||||||
|
|
||||||
> button
|
> .button
|
||||||
margin 0 28px 0 0
|
margin 0 28px 0 0
|
||||||
padding 0 8px
|
padding 0 8px
|
||||||
line-height 32px
|
line-height 32px
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-notes">
|
<div class="mk-notes" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||||
<slot name="header"></slot>
|
<slot name="header"></slot>
|
||||||
|
|
||||||
<div class="newer-indicator" :style="{ top: $store.state.uiHeaderHeight + 'px' }" v-show="queue.length > 0"></div>
|
<div class="newer-indicator" :style="{ top: $store.state.uiHeaderHeight + 'px' }" v-show="queue.length > 0"></div>
|
||||||
@@ -191,10 +191,14 @@ export default Vue.extend({
|
|||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.mk-notes
|
.mk-notes
|
||||||
background var(--face)
|
background var(--face)
|
||||||
box-shadow var(--shadow)
|
|
||||||
border-radius var(--round)
|
|
||||||
overflow hidden
|
overflow hidden
|
||||||
|
|
||||||
|
&.round
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
|
&.shadow
|
||||||
|
box-shadow 0 3px 8px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
.transition
|
.transition
|
||||||
.mk-notes-enter
|
.mk-notes-enter
|
||||||
.mk-notes-leave-to
|
.mk-notes-leave-to
|
||||||
|
|||||||
@@ -463,17 +463,26 @@ export default Vue.extend({
|
|||||||
|
|
||||||
circleIcons: {
|
circleIcons: {
|
||||||
get() { return this.$store.state.settings.circleIcons; },
|
get() { return this.$store.state.settings.circleIcons; },
|
||||||
set(value) { this.$store.dispatch('settings/set', { key: 'circleIcons', value }); }
|
set(value) {
|
||||||
|
this.$store.dispatch('settings/set', { key: 'circleIcons', value });
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
contrastedAcct: {
|
contrastedAcct: {
|
||||||
get() { return this.$store.state.settings.contrastedAcct; },
|
get() { return this.$store.state.settings.contrastedAcct; },
|
||||||
set(value) { this.$store.dispatch('settings/set', { key: 'contrastedAcct', value }); }
|
set(value) {
|
||||||
|
this.$store.dispatch('settings/set', { key: 'contrastedAcct', value });
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
showFullAcct: {
|
showFullAcct: {
|
||||||
get() { return this.$store.state.settings.showFullAcct; },
|
get() { return this.$store.state.settings.showFullAcct; },
|
||||||
set(value) { this.$store.dispatch('settings/set', { key: 'showFullAcct', value }); }
|
set(value) {
|
||||||
|
this.$store.dispatch('settings/set', { key: 'showFullAcct', value });
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
showVia: {
|
showVia: {
|
||||||
@@ -517,6 +526,17 @@ export default Vue.extend({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
reload() {
|
||||||
|
this.$root.dialog({
|
||||||
|
type: 'warning',
|
||||||
|
text: this.$t('@.reload-to-apply-the-setting'),
|
||||||
|
showCancelButton: true
|
||||||
|
}).then(({ canceled }) => {
|
||||||
|
if (!canceled) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
customizeHome() {
|
customizeHome() {
|
||||||
location.href = '/?customize';
|
location.href = '/?customize';
|
||||||
},
|
},
|
||||||
@@ -583,9 +603,6 @@ export default Vue.extend({
|
|||||||
z-index 1
|
z-index 1
|
||||||
font-size 15px
|
font-size 15px
|
||||||
|
|
||||||
&.inWindow
|
|
||||||
box-shadow var(--shadowRight)
|
|
||||||
|
|
||||||
> p
|
> p
|
||||||
display block
|
display block
|
||||||
padding 10px 16px
|
padding 10px 16px
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="kedshtep" :class="{ naked, inNakedDeckColumn }">
|
<div class="kedshtep" :class="{ naked, inNakedDeckColumn, shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||||
<header v-if="showHeader">
|
<header v-if="showHeader">
|
||||||
<div class="title"><slot name="header"></slot></div>
|
<div class="title"><slot name="header"></slot></div>
|
||||||
<slot name="func"></slot>
|
<slot name="func"></slot>
|
||||||
@@ -60,8 +60,12 @@ export default Vue.extend({
|
|||||||
|
|
||||||
&:not(.inNakedDeckColumn)
|
&:not(.inNakedDeckColumn)
|
||||||
background var(--face)
|
background var(--face)
|
||||||
box-shadow var(--shadow)
|
|
||||||
border-radius var(--round)
|
&.round
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
|
&.shadow
|
||||||
|
box-shadow 0 3px 8px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
& + .kedshtep
|
& + .kedshtep
|
||||||
margin-top 16px
|
margin-top 16px
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="header" :class="navbar">
|
<div class="header" :class="navbar" :data-shadow="$store.state.device.useShadow">
|
||||||
<div class="body">
|
<div class="body">
|
||||||
<div class="post">
|
<div class="post">
|
||||||
<button @click="post" :title="$t('title')"><fa icon="pencil-alt"/></button>
|
<button @click="post" :title="$t('title')"><fa icon="pencil-alt"/></button>
|
||||||
@@ -62,7 +62,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<transition :name="`slide-${navbar}`">
|
<transition :name="`slide-${navbar}`">
|
||||||
<div class="notifications" v-if="showNotifications" ref="notifications" :class="navbar">
|
<div class="notifications" v-if="showNotifications" ref="notifications" :class="navbar" :data-shadow="$store.state.device.useShadow">
|
||||||
<mk-notifications/>
|
<mk-notifications/>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
@@ -226,11 +226,15 @@ export default Vue.extend({
|
|||||||
|
|
||||||
&.left
|
&.left
|
||||||
left 0
|
left 0
|
||||||
box-shadow var(--shadowRight)
|
|
||||||
|
&[data-shadow]
|
||||||
|
box-shadow 4px 0 4px rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
&.right
|
&.right
|
||||||
right 0
|
right 0
|
||||||
box-shadow var(--shadowLeft)
|
|
||||||
|
&[data-shadow]
|
||||||
|
box-shadow -4px 0 4px rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
> .body
|
> .body
|
||||||
position fixed
|
position fixed
|
||||||
@@ -302,11 +306,15 @@ export default Vue.extend({
|
|||||||
|
|
||||||
&.left
|
&.left
|
||||||
left $width
|
left $width
|
||||||
box-shadow var(--shadowRight)
|
|
||||||
|
&[data-shadow]
|
||||||
|
box-shadow 4px 0 4px rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
&.right
|
&.right
|
||||||
right $width
|
right $width
|
||||||
box-shadow var(--shadowLeft)
|
|
||||||
|
&[data-shadow]
|
||||||
|
box-shadow -4px 0 4px rgba(0, 0, 0, 0.1)
|
||||||
|
|
||||||
.nav
|
.nav
|
||||||
> *
|
> *
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
<option value="users">{{ $t('@.widgets.users') }}</option>
|
<option value="users">{{ $t('@.widgets.users') }}</option>
|
||||||
<option value="polls">{{ $t('@.widgets.polls') }}</option>
|
<option value="polls">{{ $t('@.widgets.polls') }}</option>
|
||||||
<option value="post-form">{{ $t('@.widgets.post-form') }}</option>
|
<option value="post-form">{{ $t('@.widgets.post-form') }}</option>
|
||||||
<option value="messaging">{{ $t('@.widgets.messaging') }}</option>
|
<option value="messaging">{{ $t('@.messaging') }}</option>
|
||||||
<option value="memo">{{ $t('@.widgets.memo') }}</option>
|
<option value="memo">{{ $t('@.widgets.memo') }}</option>
|
||||||
<option value="hashtags">{{ $t('@.widgets.hashtags') }}</option>
|
<option value="hashtags">{{ $t('@.widgets.hashtags') }}</option>
|
||||||
<option value="posts-monitor">{{ $t('@.widgets.posts-monitor') }}</option>
|
<option value="posts-monitor">{{ $t('@.widgets.posts-monitor') }}</option>
|
||||||
@@ -109,6 +109,10 @@ export default Vue.extend({
|
|||||||
name: 'broadcast',
|
name: 'broadcast',
|
||||||
place: 'right',
|
place: 'right',
|
||||||
data: {}
|
data: {}
|
||||||
|
}, {
|
||||||
|
name: 'hashtags',
|
||||||
|
place: 'right',
|
||||||
|
data: {}
|
||||||
}];
|
}];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="pwbzawku">
|
<div class="pwbzawku">
|
||||||
<mk-post-form class="form" v-if="$store.state.settings.showPostFormOnTopOfTl"/>
|
<mk-post-form class="form" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }" v-if="$store.state.settings.showPostFormOnTopOfTl"/>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<component :is="src == 'list' ? 'mk-user-list-timeline' : 'x-core'" ref="tl" v-bind="options">
|
<component :is="src == 'list' ? 'mk-user-list-timeline' : 'x-core'" ref="tl" v-bind="options">
|
||||||
<header class="zahtxcqi">
|
<header class="zahtxcqi">
|
||||||
@@ -193,8 +193,12 @@ export default Vue.extend({
|
|||||||
.pwbzawku
|
.pwbzawku
|
||||||
> .form
|
> .form
|
||||||
margin-bottom 16px
|
margin-bottom 16px
|
||||||
box-shadow var(--shadow)
|
|
||||||
border-radius var(--round)
|
&.round
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
|
&.shadow
|
||||||
|
box-shadow 0 3px 8px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
.zahtxcqi
|
.zahtxcqi
|
||||||
padding 0 8px
|
padding 0 8px
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="omechnps" v-if="!fetching">
|
<div class="omechnps" v-if="!fetching">
|
||||||
<div class="is-suspended" v-if="user.isSuspended"><fa icon="exclamation-triangle"/> {{ $t('@.user-suspended') }}</div>
|
<div class="is-suspended" v-if="user.isSuspended" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||||
<div class="is-remote" v-if="user.host != null"><fa icon="exclamation-triangle"/> {{ $t('@.is-remote-user') }}<a :href="user.url || user.uri" target="_blank">{{ $t('@.view-on-remote') }}</a></div>
|
<fa icon="exclamation-triangle"/> {{ $t('@.user-suspended') }}
|
||||||
|
</div>
|
||||||
|
<div class="is-remote" v-if="user.host != null" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||||
|
<fa icon="exclamation-triangle"/> {{ $t('@.is-remote-user') }}<a :href="user.url || user.uri" target="_blank">{{ $t('@.view-on-remote') }}</a>
|
||||||
|
</div>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<x-header class="header" :user="user"/>
|
<x-header class="header" :user="user"/>
|
||||||
<router-view :user="user"></router-view>
|
<router-view :user="user"></router-view>
|
||||||
@@ -61,8 +65,12 @@ export default Vue.extend({
|
|||||||
margin-bottom 16px
|
margin-bottom 16px
|
||||||
padding 14px 16px
|
padding 14px 16px
|
||||||
font-size 14px
|
font-size 14px
|
||||||
box-shadow var(--shadow)
|
|
||||||
border-radius var(--round)
|
&.round
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
|
&.shadow
|
||||||
|
box-shadow 0 3px 8px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
&.is-suspended
|
&.is-suspended
|
||||||
color var(--suspendedInfoFg)
|
color var(--suspendedInfoFg)
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="vahgrswmbzfdlmomxnqftuueyvwaafth">
|
|
||||||
<p class="title"><fa icon="users"/>{{ $t('title') }}</p>
|
|
||||||
<p class="initializing" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('loading') }}<mk-ellipsis/></p>
|
|
||||||
<div v-if="!fetching && users.length > 0">
|
|
||||||
<router-link v-for="user in users" :to="user | userPage" :key="user.id">
|
|
||||||
<img :src="user.avatarUrl" :alt="user | userName" v-user-preview="user.id"/>
|
|
||||||
</router-link>
|
|
||||||
</div>
|
|
||||||
<p class="empty" v-if="!fetching && users.length == 0">{{ $t('no-users') }}</p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import Vue from 'vue';
|
|
||||||
import i18n from '../../../../i18n';
|
|
||||||
|
|
||||||
export default Vue.extend({
|
|
||||||
i18n: i18n('desktop/views/pages/user/user.followers-you-know.vue'),
|
|
||||||
props: ['user'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
users: [],
|
|
||||||
fetching: true
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$root.api('users/followers', {
|
|
||||||
userId: this.user.id,
|
|
||||||
iknow: true,
|
|
||||||
limit: 16
|
|
||||||
}).then(x => {
|
|
||||||
this.users = x.users;
|
|
||||||
this.fetching = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
|
||||||
.vahgrswmbzfdlmomxnqftuueyvwaafth
|
|
||||||
background var(--face)
|
|
||||||
box-shadow var(--shadow)
|
|
||||||
border-radius var(--round)
|
|
||||||
|
|
||||||
> .title
|
|
||||||
z-index 1
|
|
||||||
margin 0
|
|
||||||
padding 0 16px
|
|
||||||
line-height 42px
|
|
||||||
font-size 0.9em
|
|
||||||
font-weight bold
|
|
||||||
color var(--faceHeaderText)
|
|
||||||
box-shadow 0 1px rgba(#000, 0.07)
|
|
||||||
|
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
> div
|
|
||||||
padding 8px
|
|
||||||
|
|
||||||
> a
|
|
||||||
display inline-block
|
|
||||||
margin 4px
|
|
||||||
|
|
||||||
> img
|
|
||||||
display inline-block
|
|
||||||
text-align center
|
|
||||||
width 48px
|
|
||||||
height 48px
|
|
||||||
vertical-align bottom
|
|
||||||
border-radius 100%
|
|
||||||
|
|
||||||
> .initializing
|
|
||||||
> .empty
|
|
||||||
margin 0
|
|
||||||
padding 16px
|
|
||||||
text-align center
|
|
||||||
color var(--text)
|
|
||||||
|
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="hozptpaliadatkehcmcayizwzwwctpbc">
|
|
||||||
<p class="title"><fa icon="users"/>{{ $t('title') }}</p>
|
|
||||||
<p class="initializing" v-if="fetching"><fa icon="spinner" pulse fixed-width/>{{ $t('loading') }}<mk-ellipsis/></p>
|
|
||||||
<template v-if="!fetching && users.length != 0">
|
|
||||||
<div class="user" v-for="friend in users">
|
|
||||||
<mk-avatar class="avatar" :user="friend"/>
|
|
||||||
<div class="body">
|
|
||||||
<router-link class="name" :to="friend | userPage" v-user-preview="friend.id"><mk-user-name :user="friend"/></router-link>
|
|
||||||
<p class="username">@{{ friend | acct }}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<p class="empty" v-if="!fetching && users.length == 0">{{ $t('no-users') }}</p>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import Vue from 'vue';
|
|
||||||
import i18n from '../../../../i18n';
|
|
||||||
|
|
||||||
export default Vue.extend({
|
|
||||||
i18n: i18n('desktop/views/pages/user/user.friends.vue'),
|
|
||||||
props: ['user'],
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
users: [],
|
|
||||||
fetching: true
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
this.$root.api('users/get_frequently_replied_users', {
|
|
||||||
userId: this.user.id,
|
|
||||||
limit: 4
|
|
||||||
}).then(docs => {
|
|
||||||
this.users = docs.map(doc => doc.user);
|
|
||||||
this.fetching = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
|
||||||
.hozptpaliadatkehcmcayizwzwwctpbc
|
|
||||||
background var(--face)
|
|
||||||
box-shadow var(--shadow)
|
|
||||||
border-radius var(--round)
|
|
||||||
overflow hidden
|
|
||||||
|
|
||||||
> .title
|
|
||||||
z-index 1
|
|
||||||
margin 0
|
|
||||||
padding 0 16px
|
|
||||||
line-height 42px
|
|
||||||
font-size 0.9em
|
|
||||||
font-weight bold
|
|
||||||
background var(--faceHeader)
|
|
||||||
color var(--faceHeaderText)
|
|
||||||
box-shadow 0 1px rgba(#000, 0.07)
|
|
||||||
|
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
> .initializing
|
|
||||||
> .empty
|
|
||||||
margin 0
|
|
||||||
padding 16px
|
|
||||||
text-align center
|
|
||||||
color var(--text)
|
|
||||||
|
|
||||||
> i
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
> .user
|
|
||||||
padding 16px
|
|
||||||
border-bottom solid 1px var(--faceDivider)
|
|
||||||
|
|
||||||
&:last-child
|
|
||||||
border-bottom none
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
display block
|
|
||||||
clear both
|
|
||||||
|
|
||||||
> .avatar
|
|
||||||
display block
|
|
||||||
float left
|
|
||||||
margin 0 12px 0 0
|
|
||||||
width 42px
|
|
||||||
height 42px
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
> .body
|
|
||||||
float left
|
|
||||||
width calc(100% - 54px)
|
|
||||||
|
|
||||||
> .name
|
|
||||||
margin 0
|
|
||||||
font-size 16px
|
|
||||||
line-height 24px
|
|
||||||
color var(--text)
|
|
||||||
|
|
||||||
> .username
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
font-size 15px
|
|
||||||
line-height 16px
|
|
||||||
color var(--text)
|
|
||||||
opacity 0.7
|
|
||||||
|
|
||||||
</style>
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="header">
|
<div class="header" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||||
<div class="banner-container" :style="style">
|
<div class="banner-container" :style="style">
|
||||||
<div class="banner" ref="banner" :style="style" @click="onBannerClick"></div>
|
<div class="banner" ref="banner" :style="style" @click="onBannerClick"></div>
|
||||||
<div class="fade"></div>
|
<div class="fade"></div>
|
||||||
@@ -126,10 +126,14 @@ export default Vue.extend({
|
|||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.header
|
.header
|
||||||
background var(--face)
|
background var(--face)
|
||||||
box-shadow var(--shadow)
|
|
||||||
border-radius var(--round)
|
|
||||||
overflow hidden
|
overflow hidden
|
||||||
|
|
||||||
|
&.round
|
||||||
|
border-radius 6px
|
||||||
|
|
||||||
|
&.shadow
|
||||||
|
box-shadow 0 3px 8px rgba(0, 0, 0, 0.2)
|
||||||
|
|
||||||
> .banner-container
|
> .banner-container
|
||||||
height 250px
|
height 250px
|
||||||
overflow hidden
|
overflow hidden
|
||||||
|
|||||||
@@ -35,7 +35,7 @@
|
|||||||
<span class="signin" @click="signin">{{ $t('@.signin') }}</span>
|
<span class="signin" @click="signin">{{ $t('@.signin') }}</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<img :src="meta.mascotImageUrl" alt="" title="藍" class="char">
|
<img v-if="meta" :src="meta.mascotImageUrl" alt="" title="藍" class="char">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -344,8 +344,6 @@ export default Vue.extend({
|
|||||||
.block
|
.block
|
||||||
color var(--text)
|
color var(--text)
|
||||||
background var(--face)
|
background var(--face)
|
||||||
box-shadow var(--shadow)
|
|
||||||
//border-radius 8px
|
|
||||||
overflow auto
|
overflow auto
|
||||||
|
|
||||||
> header
|
> header
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import wActivity from './activity.vue';
|
|||||||
import wTrends from './trends.vue';
|
import wTrends from './trends.vue';
|
||||||
import wUsers from './users.vue';
|
import wUsers from './users.vue';
|
||||||
import wPolls from './polls.vue';
|
import wPolls from './polls.vue';
|
||||||
import wPostForm from './post-form.vue';
|
|
||||||
import wMessaging from './messaging.vue';
|
import wMessaging from './messaging.vue';
|
||||||
import wProfile from './profile.vue';
|
import wProfile from './profile.vue';
|
||||||
import wCustomize from './customize.vue';
|
import wCustomize from './customize.vue';
|
||||||
@@ -17,7 +16,6 @@ Vue.component('mkw-activity', wActivity);
|
|||||||
Vue.component('mkw-trends', wTrends);
|
Vue.component('mkw-trends', wTrends);
|
||||||
Vue.component('mkw-users', wUsers);
|
Vue.component('mkw-users', wUsers);
|
||||||
Vue.component('mkw-polls', wPolls);
|
Vue.component('mkw-polls', wPolls);
|
||||||
Vue.component('mkw-post-form', wPostForm);
|
|
||||||
Vue.component('mkw-messaging', wMessaging);
|
Vue.component('mkw-messaging', wMessaging);
|
||||||
Vue.component('mkw-profile', wProfile);
|
Vue.component('mkw-profile', wProfile);
|
||||||
Vue.component('mkw-customize', wCustomize);
|
Vue.component('mkw-customize', wCustomize);
|
||||||
|
|||||||
@@ -401,34 +401,6 @@ export default (callback: (launch: (router: VueRouter) => [Vue, MiOS], os: MiOS)
|
|||||||
console.log(`Cannot reapply theme. ${e}`);
|
console.log(`Cannot reapply theme. ${e}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region shadow
|
|
||||||
const shadow = '0 3px 8px rgba(0, 0, 0, 0.2)';
|
|
||||||
const shadowRight = '4px 0 4px rgba(0, 0, 0, 0.1)';
|
|
||||||
const shadowLeft = '-4px 0 4px rgba(0, 0, 0, 0.1)';
|
|
||||||
if (os.store.state.device.useShadow) {
|
|
||||||
document.documentElement.style.setProperty('--shadow', shadow);
|
|
||||||
document.documentElement.style.setProperty('--shadowRight', shadowRight);
|
|
||||||
document.documentElement.style.setProperty('--shadowLeft', shadowLeft);
|
|
||||||
}
|
|
||||||
os.store.watch(s => {
|
|
||||||
return s.device.useShadow;
|
|
||||||
}, v => {
|
|
||||||
document.documentElement.style.setProperty('--shadow', v ? shadow : 'none');
|
|
||||||
document.documentElement.style.setProperty('--shadowRight', v ? shadowRight : 'none');
|
|
||||||
document.documentElement.style.setProperty('--shadowLeft', v ? shadowLeft : 'none');
|
|
||||||
});
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region rounded corners
|
|
||||||
const round = '6px';
|
|
||||||
if (os.store.state.device.roundedCorners) document.documentElement.style.setProperty('--round', round);
|
|
||||||
os.store.watch(s => {
|
|
||||||
return s.device.roundedCorners;
|
|
||||||
}, v => {
|
|
||||||
document.documentElement.style.setProperty('--round', v ? round : '0');
|
|
||||||
});
|
|
||||||
//#endregion
|
|
||||||
|
|
||||||
//#region line width
|
//#region line width
|
||||||
document.documentElement.style.setProperty('--lineWidth', `${os.store.state.device.lineWidth}px`);
|
document.documentElement.style.setProperty('--lineWidth', `${os.store.state.device.lineWidth}px`);
|
||||||
os.store.watch(s => {
|
os.store.watch(s => {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="mk-note-detail" tabindex="-1" :class="{ shadow: $store.state.device.useShadow }">
|
<div class="mk-note-detail" tabindex="-1" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||||
<button
|
<button
|
||||||
class="more"
|
class="more"
|
||||||
v-if="appearNote.reply && appearNote.reply.replyId && conversation.length == 0"
|
v-if="appearNote.reply && appearNote.reply.replyId && conversation.length == 0"
|
||||||
@@ -164,7 +164,9 @@ export default Vue.extend({
|
|||||||
width 100%
|
width 100%
|
||||||
text-align left
|
text-align left
|
||||||
background var(--face)
|
background var(--face)
|
||||||
border-radius 8px
|
|
||||||
|
&.round
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
&.shadow
|
&.shadow
|
||||||
box-shadow 0 4px 16px rgba(#000, 0.1)
|
box-shadow 0 4px 16px rgba(#000, 0.1)
|
||||||
|
|||||||
@@ -36,26 +36,26 @@
|
|||||||
</div>
|
</div>
|
||||||
<span class="app" v-if="appearNote.app && $store.state.settings.showVia">via <b>{{ appearNote.app.name }}</b></span>
|
<span class="app" v-if="appearNote.app && $store.state.settings.showVia">via <b>{{ appearNote.app.name }}</b></span>
|
||||||
</div>
|
</div>
|
||||||
<footer v-if="appearNote.deletedAt == null">
|
<footer v-if="appearNote.deletedAt == null" class="footer">
|
||||||
<mk-reactions-viewer :note="appearNote" ref="reactionsViewer"/>
|
<mk-reactions-viewer :note="appearNote" ref="reactionsViewer"/>
|
||||||
<button @click="reply()">
|
<button @click="reply()" class="button">
|
||||||
<template v-if="appearNote.reply"><fa icon="reply-all"/></template>
|
<template v-if="appearNote.reply"><fa icon="reply-all"/></template>
|
||||||
<template v-else><fa icon="reply"/></template>
|
<template v-else><fa icon="reply"/></template>
|
||||||
<p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p>
|
<p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p>
|
||||||
</button>
|
</button>
|
||||||
<button v-if="['public', 'home'].includes(appearNote.visibility)" @click="renote()" title="Renote">
|
<button v-if="['public', 'home'].includes(appearNote.visibility)" @click="renote()" title="Renote" class="button">
|
||||||
<fa icon="retweet"/><p class="count" v-if="appearNote.renoteCount > 0">{{ appearNote.renoteCount }}</p>
|
<fa icon="retweet"/><p class="count" v-if="appearNote.renoteCount > 0">{{ appearNote.renoteCount }}</p>
|
||||||
</button>
|
</button>
|
||||||
<button v-else>
|
<button v-else class="button">
|
||||||
<fa icon="ban"/>
|
<fa icon="ban"/>
|
||||||
</button>
|
</button>
|
||||||
<button v-if="!isMyNote && appearNote.myReaction == null" class="reactionButton" @click="react()" ref="reactButton">
|
<button v-if="!isMyNote && appearNote.myReaction == null" class="button" @click="react()" ref="reactButton">
|
||||||
<fa icon="plus"/>
|
<fa icon="plus"/>
|
||||||
</button>
|
</button>
|
||||||
<button v-if="!isMyNote && appearNote.myReaction != null" class="reactionButton reacted" @click="undoReact(appearNote)" ref="reactButton">
|
<button v-if="!isMyNote && appearNote.myReaction != null" class="button reacted" @click="undoReact(appearNote)" ref="reactButton">
|
||||||
<fa icon="minus"/>
|
<fa icon="minus"/>
|
||||||
</button>
|
</button>
|
||||||
<button class="menu" @click="menu()" ref="menuButton">
|
<button class="button" @click="menu()" ref="menuButton">
|
||||||
<fa icon="ellipsis-h"/>
|
<fa icon="ellipsis-h"/>
|
||||||
</button>
|
</button>
|
||||||
</footer>
|
</footer>
|
||||||
@@ -107,20 +107,6 @@ export default Vue.extend({
|
|||||||
font-size 13px
|
font-size 13px
|
||||||
border-bottom solid var(--lineWidth) var(--faceDivider)
|
border-bottom solid var(--lineWidth) var(--faceDivider)
|
||||||
|
|
||||||
&:focus
|
|
||||||
z-index 1
|
|
||||||
|
|
||||||
&:after
|
|
||||||
content ""
|
|
||||||
pointer-events none
|
|
||||||
position absolute
|
|
||||||
top 2px
|
|
||||||
right 2px
|
|
||||||
bottom 2px
|
|
||||||
left 2px
|
|
||||||
border 2px solid var(--primaryAlpha03)
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
&:last-of-type
|
&:last-of-type
|
||||||
border-bottom none
|
border-bottom none
|
||||||
|
|
||||||
@@ -251,8 +237,8 @@ export default Vue.extend({
|
|||||||
font-size 12px
|
font-size 12px
|
||||||
color #ccc
|
color #ccc
|
||||||
|
|
||||||
> footer
|
> .footer
|
||||||
> button
|
> .button
|
||||||
margin 0
|
margin 0
|
||||||
padding 8px
|
padding 8px
|
||||||
background transparent
|
background transparent
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ivaojijs" :class="{ shadow: $store.state.device.useShadow }">
|
<div class="ivaojijs" :class="{ shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||||
<div class="empty" v-if="notes.length == 0 && !fetching && inited">{{ $t('@.no-notes') }}</div>
|
<div class="empty" v-if="notes.length == 0 && !fetching && inited">{{ $t('@.no-notes') }}</div>
|
||||||
|
|
||||||
<mk-error v-if="!fetching && !inited" @retry="init()"/>
|
<mk-error v-if="!fetching && !inited" @retry="init()"/>
|
||||||
@@ -191,7 +191,9 @@ export default Vue.extend({
|
|||||||
.ivaojijs
|
.ivaojijs
|
||||||
overflow hidden
|
overflow hidden
|
||||||
background var(--face)
|
background var(--face)
|
||||||
border-radius 8px
|
|
||||||
|
&.round
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
&.shadow
|
&.shadow
|
||||||
box-shadow 0 4px 16px rgba(#000, 0.1)
|
box-shadow 0 4px 16px rgba(#000, 0.1)
|
||||||
|
|||||||
@@ -61,7 +61,7 @@ export default Vue.extend({
|
|||||||
|
|
||||||
this.connection.on('notification', this.onNotification);
|
this.connection.on('notification', this.onNotification);
|
||||||
|
|
||||||
const max = 10;
|
const max = 15;
|
||||||
|
|
||||||
this.$root.api('i/notifications', {
|
this.$root.api('i/notifications', {
|
||||||
limit: max + 1
|
limit: max + 1
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="ukygtjoj" :class="{ naked, inNakedDeckColumn, hideHeader: !showHeader, shadow: $store.state.device.useShadow }">
|
<div class="ukygtjoj" :class="{ naked, inNakedDeckColumn, hideHeader: !showHeader, shadow: $store.state.device.useShadow, round: $store.state.device.roundedCorners }">
|
||||||
<header v-if="showHeader">
|
<header v-if="showHeader">
|
||||||
<div class="title"><slot name="header"></slot></div>
|
<div class="title"><slot name="header"></slot></div>
|
||||||
<slot name="func"></slot>
|
<slot name="func"></slot>
|
||||||
@@ -59,7 +59,9 @@ export default Vue.extend({
|
|||||||
|
|
||||||
&:not(.inNakedDeckColumn)
|
&:not(.inNakedDeckColumn)
|
||||||
background var(--face)
|
background var(--face)
|
||||||
border-radius 8px
|
|
||||||
|
&.round
|
||||||
|
border-radius 8px
|
||||||
|
|
||||||
&.shadow
|
&.shadow
|
||||||
box-shadow 0 4px 16px rgba(#000, 0.1)
|
box-shadow 0 4px 16px rgba(#000, 0.1)
|
||||||
@@ -82,7 +84,6 @@ export default Vue.extend({
|
|||||||
font-weight normal
|
font-weight normal
|
||||||
color var(--faceHeaderText)
|
color var(--faceHeaderText)
|
||||||
background var(--faceHeader)
|
background var(--faceHeader)
|
||||||
border-radius 8px 8px 0 0
|
|
||||||
|
|
||||||
> [data-icon]
|
> [data-icon]
|
||||||
margin-right 6px
|
margin-right 6px
|
||||||
|
|||||||
@@ -51,6 +51,7 @@
|
|||||||
<div class="notifications" v-if="showNotifications">
|
<div class="notifications" v-if="showNotifications">
|
||||||
<header>
|
<header>
|
||||||
<button @click="showNotifications = false"><fa icon="times"/></button>
|
<button @click="showNotifications = false"><fa icon="times"/></button>
|
||||||
|
<i v-if="hasUnreadNotification" class="circle"><fa icon="circle"/></i>
|
||||||
</header>
|
</header>
|
||||||
<mk-notifications/>
|
<mk-notifications/>
|
||||||
</div>
|
</div>
|
||||||
@@ -207,7 +208,7 @@ export default Vue.extend({
|
|||||||
font-size 15px
|
font-size 15px
|
||||||
|
|
||||||
&.notifications
|
&.notifications
|
||||||
width 340px
|
width 330px
|
||||||
|
|
||||||
> .notifications
|
> .notifications
|
||||||
padding-top 42px
|
padding-top 42px
|
||||||
@@ -217,7 +218,7 @@ export default Vue.extend({
|
|||||||
top 0
|
top 0
|
||||||
left 0
|
left 0
|
||||||
z-index 1000
|
z-index 1000
|
||||||
width 340px
|
width 330px
|
||||||
line-height 42px
|
line-height 42px
|
||||||
background var(--secondary)
|
background var(--secondary)
|
||||||
|
|
||||||
@@ -228,6 +229,13 @@ export default Vue.extend({
|
|||||||
line-height 42px
|
line-height 42px
|
||||||
color var(--text)
|
color var(--text)
|
||||||
|
|
||||||
|
> i
|
||||||
|
position absolute
|
||||||
|
top 0
|
||||||
|
right 16px
|
||||||
|
font-size 12px
|
||||||
|
color var(--notificationIndicator)
|
||||||
|
|
||||||
> .nav
|
> .nav
|
||||||
|
|
||||||
> .me
|
> .me
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ export default Vue.extend({
|
|||||||
position absolute
|
position absolute
|
||||||
top 0
|
top 0
|
||||||
left 0
|
left 0
|
||||||
color var(--primary)
|
color var(--notificationIndicator)
|
||||||
font-size 16px
|
font-size 16px
|
||||||
|
|
||||||
&.post
|
&.post
|
||||||
|
|||||||
@@ -308,7 +308,10 @@ export default Vue.extend({
|
|||||||
|
|
||||||
circleIcons: {
|
circleIcons: {
|
||||||
get() { return this.$store.state.settings.circleIcons; },
|
get() { return this.$store.state.settings.circleIcons; },
|
||||||
set(value) { this.$store.dispatch('settings/set', { key: 'circleIcons', value }); }
|
set(value) {
|
||||||
|
this.$store.dispatch('settings/set', { key: 'circleIcons', value });
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
lineWidth: {
|
lineWidth: {
|
||||||
@@ -318,12 +321,18 @@ export default Vue.extend({
|
|||||||
|
|
||||||
contrastedAcct: {
|
contrastedAcct: {
|
||||||
get() { return this.$store.state.settings.contrastedAcct; },
|
get() { return this.$store.state.settings.contrastedAcct; },
|
||||||
set(value) { this.$store.dispatch('settings/set', { key: 'contrastedAcct', value }); }
|
set(value) {
|
||||||
|
this.$store.dispatch('settings/set', { key: 'contrastedAcct', value });
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
showFullAcct: {
|
showFullAcct: {
|
||||||
get() { return this.$store.state.settings.showFullAcct; },
|
get() { return this.$store.state.settings.showFullAcct; },
|
||||||
set(value) { this.$store.dispatch('settings/set', { key: 'showFullAcct', value }); }
|
set(value) {
|
||||||
|
this.$store.dispatch('settings/set', { key: 'showFullAcct', value });
|
||||||
|
this.reload();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
showVia: {
|
showVia: {
|
||||||
@@ -396,6 +405,18 @@ export default Vue.extend({
|
|||||||
this.$root.signout();
|
this.$root.signout();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
reload() {
|
||||||
|
this.$root.dialog({
|
||||||
|
type: 'warning',
|
||||||
|
text: this.$t('@.reload-to-apply-the-setting'),
|
||||||
|
showCancelButton: true
|
||||||
|
}).then(({ canceled }) => {
|
||||||
|
if (!canceled) {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
checkForUpdate() {
|
checkForUpdate() {
|
||||||
this.checkingForUpdate = true;
|
this.checkingForUpdate = true;
|
||||||
checkForUpdate(this.$root, true, true).then(newer => {
|
checkForUpdate(this.$root, true, true).then(newer => {
|
||||||
|
|||||||
@@ -44,7 +44,14 @@ export const meta = {
|
|||||||
'-attachedRemoteUsers',
|
'-attachedRemoteUsers',
|
||||||
]),
|
]),
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
|
||||||
|
res: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
type: 'Hashtag'
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const sort: any = {
|
const sort: any = {
|
||||||
|
|||||||
@@ -35,7 +35,14 @@ export const meta = {
|
|||||||
'ja-JP': 'オフセット'
|
'ja-JP': 'オフセット'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
res: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
type: 'string'
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default define(meta, async (ps) => {
|
export default define(meta, async (ps) => {
|
||||||
|
|||||||
@@ -44,7 +44,14 @@ export const meta = {
|
|||||||
]),
|
]),
|
||||||
default: 'local'
|
default: 'local'
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
res: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
type: 'User'
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
const sort: any = {
|
const sort: any = {
|
||||||
|
|||||||
@@ -46,6 +46,13 @@ export const meta = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
res: {
|
||||||
|
type: 'array',
|
||||||
|
items: {
|
||||||
|
type: 'Reaction'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
errors: {
|
errors: {
|
||||||
noSuchNote: {
|
noSuchNote: {
|
||||||
message: 'No such note.',
|
message: 'No such note.',
|
||||||
|
|||||||
@@ -312,7 +312,7 @@ export const schemas = {
|
|||||||
example: 'xxxxxxxxxxxxxxxxxxxxxxxx',
|
example: 'xxxxxxxxxxxxxxxxxxxxxxxx',
|
||||||
},
|
},
|
||||||
parent: {
|
parent: {
|
||||||
type: 'DriveFolder',
|
$ref: '#/components/schemas/DriveFolder'
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
required: ['id', 'createdAt', 'name']
|
required: ['id', 'createdAt', 'name']
|
||||||
@@ -361,4 +361,86 @@ export const schemas = {
|
|||||||
},
|
},
|
||||||
required: ['id', 'createdAt', 'blockee']
|
required: ['id', 'createdAt', 'blockee']
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Reaction: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
id: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'id',
|
||||||
|
description: 'The unique identifier for this reaction.',
|
||||||
|
example: 'xxxxxxxxxxxxxxxxxxxxxxxx',
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
type: 'string',
|
||||||
|
format: 'date-time',
|
||||||
|
description: 'The date that the reaction was created.'
|
||||||
|
},
|
||||||
|
user: {
|
||||||
|
$ref: '#/components/schemas/User',
|
||||||
|
description: 'User who performed this reaction.'
|
||||||
|
},
|
||||||
|
type: {
|
||||||
|
type: 'string',
|
||||||
|
enum: [
|
||||||
|
'like',
|
||||||
|
'love',
|
||||||
|
'laugh',
|
||||||
|
'hmm',
|
||||||
|
'surprise',
|
||||||
|
'congrats',
|
||||||
|
'angry',
|
||||||
|
'confused',
|
||||||
|
'rip',
|
||||||
|
'pudding'
|
||||||
|
],
|
||||||
|
description: 'The reaction type.'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ['id', 'createdAt', 'user', 'type']
|
||||||
|
},
|
||||||
|
|
||||||
|
Hashtag: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
tag: {
|
||||||
|
type: 'string',
|
||||||
|
description: 'The hashtag name. No # prefixed.',
|
||||||
|
example: 'misskey',
|
||||||
|
},
|
||||||
|
mentionedUsersCount: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Number of all users using this hashtag.'
|
||||||
|
},
|
||||||
|
mentionedLocalUsersCount: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Number of local users using this hashtag.'
|
||||||
|
},
|
||||||
|
mentionedRemoteUsersCount: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Number of remote users using this hashtag.'
|
||||||
|
},
|
||||||
|
attachedUsersCount: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Number of all users who attached this hashtag to profile.'
|
||||||
|
},
|
||||||
|
attachedLocalUsersCount: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Number of local users who attached this hashtag to profile.'
|
||||||
|
},
|
||||||
|
attachedRemoteUsersCount: {
|
||||||
|
type: 'number',
|
||||||
|
description: 'Number of remote users who attached this hashtag to profile.'
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: [
|
||||||
|
'tag',
|
||||||
|
'mentionedUsersCount',
|
||||||
|
'mentionedLocalUsersCount',
|
||||||
|
'mentionedRemoteUsersCount',
|
||||||
|
'attachedUsersCount',
|
||||||
|
'attachedLocalUsersCount',
|
||||||
|
'attachedRemoteUsersCount',
|
||||||
|
]
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -2,10 +2,15 @@ import * as Koa from 'koa';
|
|||||||
import * as request from 'request-promise-native';
|
import * as request from 'request-promise-native';
|
||||||
import summaly from 'summaly';
|
import summaly from 'summaly';
|
||||||
import fetchMeta from '../../misc/fetch-meta';
|
import fetchMeta from '../../misc/fetch-meta';
|
||||||
|
import Logger from '../../misc/logger';
|
||||||
|
|
||||||
|
const logger = new Logger('url-preview');
|
||||||
|
|
||||||
module.exports = async (ctx: Koa.BaseContext) => {
|
module.exports = async (ctx: Koa.BaseContext) => {
|
||||||
const meta = await fetchMeta();
|
const meta = await fetchMeta();
|
||||||
|
|
||||||
|
logger.info(`Getting preview of ${ctx.query.url} ...`);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const summary = meta.summalyProxy ? await request.get({
|
const summary = meta.summalyProxy ? await request.get({
|
||||||
url: meta.summalyProxy,
|
url: meta.summalyProxy,
|
||||||
@@ -17,6 +22,8 @@ module.exports = async (ctx: Koa.BaseContext) => {
|
|||||||
followRedirects: false
|
followRedirects: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
logger.succ(`Got preview of ${ctx.query.url}: ${summary.title}`);
|
||||||
|
|
||||||
summary.icon = wrap(summary.icon);
|
summary.icon = wrap(summary.icon);
|
||||||
summary.thumbnail = wrap(summary.thumbnail);
|
summary.thumbnail = wrap(summary.thumbnail);
|
||||||
|
|
||||||
@@ -25,6 +32,7 @@ module.exports = async (ctx: Koa.BaseContext) => {
|
|||||||
|
|
||||||
ctx.body = summary;
|
ctx.body = summary;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
logger.error(`Failed to get preview of ${ctx.query.url}: ${e}`);
|
||||||
ctx.status = 200;
|
ctx.status = 200;
|
||||||
ctx.set('Cache-Control', 'max-age=86400, immutable');
|
ctx.set('Cache-Control', 'max-age=86400, immutable');
|
||||||
ctx.body = '{}';
|
ctx.body = '{}';
|
||||||
|
|||||||
Reference in New Issue
Block a user