* wip
* wip
* Clean up
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* wip
* 🎨
* wip
* wip
This commit is contained in:
parent
c1a929022f
commit
fef4f7fce8
29 changed files with 824 additions and 833 deletions
|
@ -456,6 +456,26 @@ common/views/components/trends.vue:
|
||||||
count: "{}人が投稿"
|
count: "{}人が投稿"
|
||||||
empty: "トレンドなし"
|
empty: "トレンドなし"
|
||||||
|
|
||||||
|
common/views/components/profile-editor.vue:
|
||||||
|
title: "プロフィール"
|
||||||
|
name: "名前"
|
||||||
|
account: "アカウント"
|
||||||
|
location: "場所"
|
||||||
|
description: "自己紹介"
|
||||||
|
birthday: "誕生日"
|
||||||
|
avatar: "アイコン"
|
||||||
|
banner: "バナー"
|
||||||
|
is-cat: "このアカウントはCatです"
|
||||||
|
is-bot: "このアカウントはBotです"
|
||||||
|
is-locked: "フォローを承認制にする"
|
||||||
|
careful-bot: "Botからのフォローだけ承認制にする"
|
||||||
|
advanced: "その他"
|
||||||
|
privacy: "プライバシー"
|
||||||
|
save: "保存"
|
||||||
|
saved: "プロフィールを保存しました"
|
||||||
|
uploading: "アップロード中"
|
||||||
|
upload-failed: "アップロードに失敗しました"
|
||||||
|
|
||||||
common/views/widgets/broadcast.vue:
|
common/views/widgets/broadcast.vue:
|
||||||
fetching: "確認中"
|
fetching: "確認中"
|
||||||
no-broadcasts: "お知らせはありません"
|
no-broadcasts: "お知らせはありません"
|
||||||
|
@ -814,9 +834,12 @@ desktop/views/components/settings.vue:
|
||||||
advanced: "詳細設定"
|
advanced: "詳細設定"
|
||||||
api-via-stream: "ストリームを経由したAPIリクエスト"
|
api-via-stream: "ストリームを経由したAPIリクエスト"
|
||||||
api-via-stream-desc: "この設定をオンにすると、websocket接続を経由してAPIリクエストが行われます(パフォーマンス向上が期待できます)。オフにすると、ネイティブの fetch APIが利用されます。この設定はこのデバイスのみ有効です。"
|
api-via-stream-desc: "この設定をオンにすると、websocket接続を経由してAPIリクエストが行われます(パフォーマンス向上が期待できます)。オフにすると、ネイティブの fetch APIが利用されます。この設定はこのデバイスのみ有効です。"
|
||||||
|
deck-nav: "デッキ内ナビゲーション"
|
||||||
|
deck-nav-desc: "デッキを使用しているとき、ナビゲーションが発生する際にページ遷移を行わずに一時的なカラムで受けるようにします。"
|
||||||
|
|
||||||
display: "デザインと表示"
|
display: "デザインと表示"
|
||||||
customize: "ホームをカスタマイズ"
|
customize: "ホームをカスタマイズ"
|
||||||
|
wallpaper: "壁紙"
|
||||||
choose-wallpaper: "壁紙を選択"
|
choose-wallpaper: "壁紙を選択"
|
||||||
delete-wallpaper: "壁紙を削除"
|
delete-wallpaper: "壁紙を削除"
|
||||||
dark-mode: "ダークモード"
|
dark-mode: "ダークモード"
|
||||||
|
@ -839,9 +862,6 @@ desktop/views/components/settings.vue:
|
||||||
volume: "ボリューム"
|
volume: "ボリューム"
|
||||||
test: "テスト"
|
test: "テスト"
|
||||||
|
|
||||||
mobile: "モバイル"
|
|
||||||
disable-via-mobile: "「モバイルからの投稿」フラグを付けない"
|
|
||||||
|
|
||||||
language: "言語"
|
language: "言語"
|
||||||
pick-language: "言語を選択"
|
pick-language: "言語を選択"
|
||||||
recommended: "推奨"
|
recommended: "推奨"
|
||||||
|
@ -933,22 +953,6 @@ desktop/views/components/settings.password.vue:
|
||||||
not-match: "新しいパスワードが一致しません"
|
not-match: "新しいパスワードが一致しません"
|
||||||
changed: "パスワードを変更しました"
|
changed: "パスワードを変更しました"
|
||||||
|
|
||||||
desktop/views/components/settings.profile.vue:
|
|
||||||
avatar: "アイコン"
|
|
||||||
choice-avatar: "画像を選択"
|
|
||||||
name: "名前"
|
|
||||||
location: "場所"
|
|
||||||
description: "自己紹介"
|
|
||||||
birthday: "誕生日"
|
|
||||||
save: "保存"
|
|
||||||
locked-account: "アカウントの保護"
|
|
||||||
is-locked: "フォローを承認制にする"
|
|
||||||
careful-bot: "Botからのフォローだけ承認制にする"
|
|
||||||
other: "その他"
|
|
||||||
is-bot: "このアカウントはBotです"
|
|
||||||
is-cat: "このアカウントはCatです"
|
|
||||||
profile-updated: "プロフィールを更新しました"
|
|
||||||
|
|
||||||
desktop/views/components/sub-note-content.vue:
|
desktop/views/components/sub-note-content.vue:
|
||||||
private: "この投稿は非公開です"
|
private: "この投稿は非公開です"
|
||||||
deleted: "この投稿は削除されました"
|
deleted: "この投稿は削除されました"
|
||||||
|
@ -1069,11 +1073,6 @@ desktop/views/pages/deck/deck.tl-column.vue:
|
||||||
is-media-view: "メディアビュー"
|
is-media-view: "メディアビュー"
|
||||||
edit: "オプション"
|
edit: "オプション"
|
||||||
|
|
||||||
desktop/views/pages/deck/deck.note.vue:
|
|
||||||
reposted-by: "{}がRenote"
|
|
||||||
private: "この投稿は非公開です"
|
|
||||||
deleted: "この投稿は削除されました"
|
|
||||||
|
|
||||||
desktop/views/pages/stats/stats.vue:
|
desktop/views/pages/stats/stats.vue:
|
||||||
all-users: "全てのユーザー"
|
all-users: "全てのユーザー"
|
||||||
original-users: "このインスタンスのユーザー"
|
original-users: "このインスタンスのユーザー"
|
||||||
|
@ -1417,25 +1416,6 @@ mobile/views/pages/notifications.vue:
|
||||||
mobile/views/pages/games/reversi.vue:
|
mobile/views/pages/games/reversi.vue:
|
||||||
reversi: "リバーシ"
|
reversi: "リバーシ"
|
||||||
|
|
||||||
mobile/views/pages/settings/settings.profile.vue:
|
|
||||||
title: "プロフィール"
|
|
||||||
name: "名前"
|
|
||||||
account: "アカウント"
|
|
||||||
location: "場所"
|
|
||||||
description: "自己紹介"
|
|
||||||
birthday: "誕生日"
|
|
||||||
avatar: "アイコン"
|
|
||||||
banner: "バナー"
|
|
||||||
is-cat: "このアカウントはCatです"
|
|
||||||
is-locked: "フォローを承認制にする"
|
|
||||||
careful-bot: "Botからのフォローだけ承認制にする"
|
|
||||||
advanced: "その他"
|
|
||||||
privacy: "プライバシー"
|
|
||||||
save: "保存"
|
|
||||||
saved: "プロフィールを保存しました"
|
|
||||||
uploading: "アップロード中"
|
|
||||||
upload-failed: "アップロードに失敗しました"
|
|
||||||
|
|
||||||
mobile/views/pages/search.vue:
|
mobile/views/pages/search.vue:
|
||||||
search: "検索"
|
search: "検索"
|
||||||
empty: "「{}」に関する投稿は見つかりませんでした。"
|
empty: "「{}」に関する投稿は見つかりませんでした。"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
|
import profileEditor from './profile-editor.vue';
|
||||||
import noteSkeleton from './note-skeleton.vue';
|
import noteSkeleton from './note-skeleton.vue';
|
||||||
import theme from './theme.vue';
|
import theme from './theme.vue';
|
||||||
import instance from './instance.vue';
|
import instance from './instance.vue';
|
||||||
|
@ -45,6 +46,7 @@ import uiSelect from './ui/select.vue';
|
||||||
import formButton from './ui/form/button.vue';
|
import formButton from './ui/form/button.vue';
|
||||||
import formRadio from './ui/form/radio.vue';
|
import formRadio from './ui/form/radio.vue';
|
||||||
|
|
||||||
|
Vue.component('mk-profile-editor', profileEditor);
|
||||||
Vue.component('mk-note-skeleton', noteSkeleton);
|
Vue.component('mk-note-skeleton', noteSkeleton);
|
||||||
Vue.component('mk-theme', theme);
|
Vue.component('mk-theme', theme);
|
||||||
Vue.component('mk-instance', instance);
|
Vue.component('mk-instance', instance);
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<ui-switch v-model="isCat" @change="save(false)">%i18n:@is-cat%</ui-switch>
|
<ui-switch v-model="isCat" @change="save(false)">%i18n:@is-cat%</ui-switch>
|
||||||
|
<ui-switch v-model="isBot" @change="save(false)">%i18n:@is-bot%</ui-switch>
|
||||||
<ui-switch v-model="alwaysMarkNsfw">%i18n:common.always-mark-nsfw%</ui-switch>
|
<ui-switch v-model="alwaysMarkNsfw">%i18n:common.always-mark-nsfw%</ui-switch>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -66,7 +67,7 @@
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import { apiUrl, host } from '../../../../config';
|
import { apiUrl, host } from '../../../config';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
data() {
|
data() {
|
||||||
|
@ -80,6 +81,7 @@ export default Vue.extend({
|
||||||
avatarId: null,
|
avatarId: null,
|
||||||
bannerId: null,
|
bannerId: null,
|
||||||
isCat: false,
|
isCat: false,
|
||||||
|
isBot: false,
|
||||||
isLocked: false,
|
isLocked: false,
|
||||||
carefulBot: false,
|
carefulBot: false,
|
||||||
saving: false,
|
saving: false,
|
||||||
|
@ -104,6 +106,7 @@ export default Vue.extend({
|
||||||
this.avatarId = this.$store.state.i.avatarId;
|
this.avatarId = this.$store.state.i.avatarId;
|
||||||
this.bannerId = this.$store.state.i.bannerId;
|
this.bannerId = this.$store.state.i.bannerId;
|
||||||
this.isCat = this.$store.state.i.isCat;
|
this.isCat = this.$store.state.i.isCat;
|
||||||
|
this.isBot = this.$store.state.i.isBot;
|
||||||
this.isLocked = this.$store.state.i.isLocked;
|
this.isLocked = this.$store.state.i.isLocked;
|
||||||
this.carefulBot = this.$store.state.i.carefulBot;
|
this.carefulBot = this.$store.state.i.carefulBot;
|
||||||
},
|
},
|
||||||
|
@ -164,6 +167,7 @@ export default Vue.extend({
|
||||||
avatarId: this.avatarId,
|
avatarId: this.avatarId,
|
||||||
bannerId: this.bannerId,
|
bannerId: this.bannerId,
|
||||||
isCat: this.isCat,
|
isCat: this.isCat,
|
||||||
|
isBot: this.isBot,
|
||||||
isLocked: this.isLocked,
|
isLocked: this.isLocked,
|
||||||
carefulBot: this.carefulBot
|
carefulBot: this.carefulBot
|
||||||
}).then(i => {
|
}).then(i => {
|
|
@ -122,17 +122,19 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
if (this.$refs.prefix) {
|
this.$nextTick(() => {
|
||||||
this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px';
|
if (this.$refs.prefix) {
|
||||||
if (this.$refs.prefix.offsetWidth) {
|
this.$refs.label.style.left = (this.$refs.prefix.offsetLeft + this.$refs.prefix.offsetWidth) + 'px';
|
||||||
this.$refs.input.style.paddingLeft = this.$refs.prefix.offsetWidth + 'px';
|
if (this.$refs.prefix.offsetWidth) {
|
||||||
|
this.$refs.input.style.paddingLeft = this.$refs.prefix.offsetWidth + 'px';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (this.$refs.suffix) {
|
||||||
if (this.$refs.suffix) {
|
if (this.$refs.suffix.offsetWidth) {
|
||||||
if (this.$refs.suffix.offsetWidth) {
|
this.$refs.input.style.paddingRight = this.$refs.suffix.offsetWidth + 'px';
|
||||||
this.$refs.input.style.paddingRight = this.$refs.suffix.offsetWidth + 'px';
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
focus() {
|
focus() {
|
||||||
|
|
|
@ -73,9 +73,6 @@ export default define({
|
||||||
border-radius 8px
|
border-radius 8px
|
||||||
|
|
||||||
.stream
|
.stream
|
||||||
display -webkit-flex
|
|
||||||
display -moz-flex
|
|
||||||
display -ms-flex
|
|
||||||
display flex
|
display flex
|
||||||
justify-content center
|
justify-content center
|
||||||
flex-wrap wrap
|
flex-wrap wrap
|
||||||
|
|
|
@ -67,8 +67,8 @@ init(async (launch) => {
|
||||||
{ path: '/tags/:tag', component: MkTag },
|
{ path: '/tags/:tag', component: MkTag },
|
||||||
{ path: '/share', component: MkShare },
|
{ path: '/share', component: MkShare },
|
||||||
{ path: '/reversi/:game?', component: MkReversi },
|
{ path: '/reversi/:game?', component: MkReversi },
|
||||||
{ path: '/@:user', component: MkUser },
|
{ path: '/@:user', name: 'user', component: MkUser },
|
||||||
{ path: '/notes/:note', component: MkNote },
|
{ path: '/notes/:note', name: 'note', component: MkNote },
|
||||||
{ path: '/authorize-follow', component: MkFollow }
|
{ path: '/authorize-follow', component: MkFollow }
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
|
@ -91,7 +91,7 @@ import MkPostFormWindow from './post-form-window.vue';
|
||||||
import MkRenoteFormWindow from './renote-form-window.vue';
|
import MkRenoteFormWindow from './renote-form-window.vue';
|
||||||
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
|
import MkNoteMenu from '../../../common/views/components/note-menu.vue';
|
||||||
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
|
import MkReactionPicker from '../../../common/views/components/reaction-picker.vue';
|
||||||
import XSub from './notes.note.sub.vue';
|
import XSub from './note.sub.vue';
|
||||||
import { sum } from '../../../../../prelude/array';
|
import { sum } from '../../../../../prelude/array';
|
||||||
import noteSubscriber from '../../../common/scripts/note-subscriber';
|
import noteSubscriber from '../../../common/scripts/note-subscriber';
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="tkfdzaxtkdeianobciwadajxzbddorql" :title="title">
|
<div class="tkfdzaxtkdeianobciwadajxzbddorql" :class="{ mini }" :title="title">
|
||||||
<mk-avatar class="avatar" :user="note.user"/>
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
<div class="main">
|
<div class="main">
|
||||||
<mk-note-header class="header" :note="note"/>
|
<mk-note-header class="header" :note="note"/>
|
||||||
|
@ -24,6 +24,11 @@ export default Vue.extend({
|
||||||
note: {
|
note: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
mini: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -44,11 +49,19 @@ export default Vue.extend({
|
||||||
<style lang="stylus" scoped>
|
<style lang="stylus" scoped>
|
||||||
.tkfdzaxtkdeianobciwadajxzbddorql
|
.tkfdzaxtkdeianobciwadajxzbddorql
|
||||||
display flex
|
display flex
|
||||||
margin 0
|
|
||||||
padding 16px 32px
|
padding 16px 32px
|
||||||
font-size 0.9em
|
font-size 0.9em
|
||||||
background var(--subNoteBg)
|
background var(--subNoteBg)
|
||||||
|
|
||||||
|
&.mini
|
||||||
|
padding 16px
|
||||||
|
font-size 10px
|
||||||
|
|
||||||
|
> .avatar
|
||||||
|
margin 0 8px 0 0
|
||||||
|
width 38px
|
||||||
|
height 38px
|
||||||
|
|
||||||
> .avatar
|
> .avatar
|
||||||
flex-shrink 0
|
flex-shrink 0
|
||||||
display block
|
display block
|
|
@ -1,7 +1,17 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="note" v-show="appearNote.deletedAt == null" :tabindex="appearNote.deletedAt == null ? '-1' : null" v-hotkey="keymap" :title="title">
|
<div
|
||||||
|
class="note"
|
||||||
|
:class="{ mini }"
|
||||||
|
v-show="appearNote.deletedAt == null"
|
||||||
|
:tabindex="appearNote.deletedAt == null ? '-1' : null"
|
||||||
|
v-hotkey="keymap"
|
||||||
|
:title="title"
|
||||||
|
>
|
||||||
|
<div class="conversation" v-if="detail && conversation.length > 0">
|
||||||
|
<x-sub v-for="note in conversation" :key="note.id" :note="note" :mini="mini"/>
|
||||||
|
</div>
|
||||||
<div class="reply-to" v-if="appearNote.reply && (!$store.getters.isSignedIn || $store.state.settings.showReplyTarget)">
|
<div class="reply-to" v-if="appearNote.reply && (!$store.getters.isSignedIn || $store.state.settings.showReplyTarget)">
|
||||||
<x-sub :note="appearNote.reply"/>
|
<x-sub :note="appearNote.reply" :mini="mini"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="renote" v-if="isRenote">
|
<div class="renote" v-if="isRenote">
|
||||||
<mk-avatar class="avatar" :user="note.user"/>
|
<mk-avatar class="avatar" :user="note.user"/>
|
||||||
|
@ -32,8 +42,8 @@
|
||||||
</div>
|
</div>
|
||||||
<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: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:map-marker-alt% 位置情報</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" :mini="mini"/></div>
|
||||||
<mk-url-preview v-for="url in urls" :url="url" :key="url"/>
|
<mk-url-preview v-for="url in urls" :url="url" :key="url" :mini="mini"/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<footer>
|
<footer>
|
||||||
|
@ -55,15 +65,16 @@
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
</article>
|
</article>
|
||||||
|
<div class="replies" v-if="detail && replies.length > 0">
|
||||||
|
<x-sub v-for="note in replies" :key="note.id" :note="note" :mini="mini"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
import MkPostFormWindow from './post-form-window.vue';
|
import XSub from './note.sub.vue';
|
||||||
import MkRenoteFormWindow from './renote-form-window.vue';
|
|
||||||
import XSub from './notes.note.sub.vue';
|
|
||||||
import noteMixin from '../../../common/scripts/note-mixin';
|
import noteMixin from '../../../common/scripts/note-mixin';
|
||||||
import noteSubscriber from '../../../common/scripts/note-subscriber';
|
import noteSubscriber from '../../../common/scripts/note-subscriber';
|
||||||
|
|
||||||
|
@ -81,6 +92,40 @@ export default Vue.extend({
|
||||||
note: {
|
note: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
detail: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
mini: {
|
||||||
|
type: Boolean,
|
||||||
|
required: false,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
conversation: [],
|
||||||
|
replies: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
if (this.detail) {
|
||||||
|
(this as any).api('notes/replies', {
|
||||||
|
noteId: this.appearNote.id,
|
||||||
|
limit: 8
|
||||||
|
}).then(replies => {
|
||||||
|
this.replies = replies;
|
||||||
|
});
|
||||||
|
|
||||||
|
(this as any).api('notes/conversation', {
|
||||||
|
noteId: this.appearNote.replyId
|
||||||
|
}).then(conversation => {
|
||||||
|
this.conversation = conversation.reverse();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -93,14 +138,23 @@ export default Vue.extend({
|
||||||
background var(--face)
|
background var(--face)
|
||||||
border-bottom solid 1px var(--faceDivider)
|
border-bottom solid 1px var(--faceDivider)
|
||||||
|
|
||||||
&[data-round]
|
&.mini
|
||||||
&:first-child
|
font-size 13px
|
||||||
border-top-left-radius 6px
|
|
||||||
border-top-right-radius 6px
|
|
||||||
|
|
||||||
> .renote
|
> .renote
|
||||||
border-top-left-radius 6px
|
padding 8px 16px 0 16px
|
||||||
border-top-right-radius 6px
|
|
||||||
|
.avatar
|
||||||
|
width 20px
|
||||||
|
height 20px
|
||||||
|
|
||||||
|
> article
|
||||||
|
padding 16px 16px 4px
|
||||||
|
|
||||||
|
> .avatar
|
||||||
|
margin 0 10px 8px 0
|
||||||
|
width 42px
|
||||||
|
height 42px
|
||||||
|
|
||||||
&:last-of-type
|
&:last-of-type
|
||||||
border-bottom none
|
border-bottom none
|
||||||
|
@ -129,6 +183,7 @@ export default Vue.extend({
|
||||||
background linear-gradient(to bottom, var(--renoteGradient) 0%, var(--face) 100%)
|
background linear-gradient(to bottom, var(--renoteGradient) 0%, var(--face) 100%)
|
||||||
|
|
||||||
.avatar
|
.avatar
|
||||||
|
flex-shrink 0
|
||||||
display inline-block
|
display inline-block
|
||||||
width 28px
|
width 28px
|
||||||
height 28px
|
height 28px
|
||||||
|
@ -273,6 +328,9 @@ export default Vue.extend({
|
||||||
border none
|
border none
|
||||||
cursor pointer
|
cursor pointer
|
||||||
|
|
||||||
|
&:last-child
|
||||||
|
margin-right 0
|
||||||
|
|
||||||
&:hover
|
&:hover
|
||||||
color var(--noteActionsHover)
|
color var(--noteActionsHover)
|
||||||
|
|
|
@ -40,7 +40,7 @@ import Vue from 'vue';
|
||||||
import * as config from '../../../config';
|
import * as config from '../../../config';
|
||||||
import getNoteSummary from '../../../../../misc/get-note-summary';
|
import getNoteSummary from '../../../../../misc/get-note-summary';
|
||||||
|
|
||||||
import XNote from './notes.note.vue';
|
import XNote from './note.vue';
|
||||||
|
|
||||||
const displayLimit = 30;
|
const displayLimit = 30;
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
<div class="2fa">
|
<div class="2fa">
|
||||||
<p>%i18n:@intro%<a href="%i18n:@url%" target="_blank">%i18n:@detail%</a></p>
|
<p>%i18n:@intro%<a href="%i18n:@url%" target="_blank">%i18n:@detail%</a></p>
|
||||||
<div class="ui info warn"><p>%fa:exclamation-triangle%%i18n:@caution%</p></div>
|
<div class="ui info warn"><p>%fa:exclamation-triangle%%i18n:@caution%</p></div>
|
||||||
<p v-if="!data && !$store.state.i.twoFactorEnabled"><button @click="register" class="ui primary">%i18n:@register%</button></p>
|
<p v-if="!data && !$store.state.i.twoFactorEnabled"><ui-button @click="register">%i18n:@register%</ui-button></p>
|
||||||
<template v-if="$store.state.i.twoFactorEnabled">
|
<template v-if="$store.state.i.twoFactorEnabled">
|
||||||
<p>%i18n:@already-registered%</p>
|
<p>%i18n:@already-registered%</p>
|
||||||
<button @click="unregister" class="ui">%i18n:@unregister%</button>
|
<ui-button @click="unregister">%i18n:@unregister%</ui-button>
|
||||||
</template>
|
</template>
|
||||||
<div v-if="data">
|
<div v-if="data">
|
||||||
<ol>
|
<ol>
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
<li>%i18n:@scan%<br><img :src="data.qr"></li>
|
<li>%i18n:@scan%<br><img :src="data.qr"></li>
|
||||||
<li>%i18n:@done%<br>
|
<li>%i18n:@done%<br>
|
||||||
<input type="number" v-model="token" class="ui">
|
<input type="number" v-model="token" class="ui">
|
||||||
<button @click="submit" class="ui primary">%i18n:@submit%</button>
|
<ui-button primary @click="submit">%i18n:@submit%</ui-button>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<div class="ui info"><p>%fa:info-circle%%i18n:@info%</p></div>
|
<div class="ui info"><p>%fa:info-circle%%i18n:@info%</p></div>
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="root api">
|
<div class="root api">
|
||||||
<p>%i18n:@token% <code>{{ $store.state.i.token }}</code></p>
|
<ui-input :value="$store.state.i.token" readonly>
|
||||||
|
<span>%i18n:@token%</span>
|
||||||
|
</ui-input>
|
||||||
<p>%i18n:@intro%</p>
|
<p>%i18n:@intro%</p>
|
||||||
<div class="ui info warn"><p>%fa:exclamation-triangle%%i18n:@caution%</p></div>
|
<div class="ui info warn"><p>%fa:exclamation-triangle%%i18n:@caution%</p></div>
|
||||||
<p>%i18n:@regeneration-of-token%</p>
|
<p>%i18n:@regeneration-of-token%</p>
|
||||||
<button class="ui" @click="regenerateToken">%i18n:@regenerate-token%</button>
|
<ui-button @click="regenerateToken">%i18n:@regenerate-token%</ui-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<button @click="reset" class="ui primary">%i18n:@reset%</button>
|
<ui-button @click="reset">%i18n:@reset%</ui-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
|
@ -1,106 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="profile">
|
|
||||||
<label class="avatar ui from group">
|
|
||||||
<p>%i18n:@avatar%</p>
|
|
||||||
<img class="avatar" :src="$store.state.i.avatarUrl" alt="avatar"/>
|
|
||||||
<button class="ui" @click="updateAvatar">%i18n:@choice-avatar%</button>
|
|
||||||
</label>
|
|
||||||
<label class="ui from group">
|
|
||||||
<ui-input v-model="name" type="text">%i18n:@name%</ui-input>
|
|
||||||
</label>
|
|
||||||
<label class="ui from group">
|
|
||||||
<ui-input v-model="location" type="text">%i18n:@location%</ui-input>
|
|
||||||
</label>
|
|
||||||
<label class="ui from group">
|
|
||||||
<ui-textarea v-model="description">%i18n:@description%</ui-textarea>
|
|
||||||
</label>
|
|
||||||
<label class="ui from group">
|
|
||||||
<p>%i18n:@birthday%</p>
|
|
||||||
<input type="date" v-model="birthday"/>
|
|
||||||
</label>
|
|
||||||
<ui-button primary @click="save">%i18n:@save%</ui-button>
|
|
||||||
<section>
|
|
||||||
<h2>%i18n:@locked-account%</h2>
|
|
||||||
<ui-switch v-model="isLocked" @change="save(false)">%i18n:@is-locked%</ui-switch>
|
|
||||||
<ui-switch v-model="carefulBot" @change="save(false)">%i18n:@careful-bot%</ui-switch>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>%i18n:@other%</h2>
|
|
||||||
<ui-switch v-model="isBot" @change="save(false)">%i18n:@is-bot%</ui-switch>
|
|
||||||
<ui-switch v-model="isCat" @change="save(false)">%i18n:@is-cat%</ui-switch>
|
|
||||||
<ui-switch v-model="alwaysMarkNsfw">%i18n:common.always-mark-nsfw%</ui-switch>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import Vue from 'vue';
|
|
||||||
|
|
||||||
export default Vue.extend({
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
name: null,
|
|
||||||
location: null,
|
|
||||||
description: null,
|
|
||||||
birthday: null,
|
|
||||||
isBot: false,
|
|
||||||
isCat: false,
|
|
||||||
isLocked: false,
|
|
||||||
carefulBot: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
alwaysMarkNsfw: {
|
|
||||||
get() { return this.$store.state.i.settings.alwaysMarkNsfw; },
|
|
||||||
set(value) { (this as any).api('i/update', { alwaysMarkNsfw: value }); }
|
|
||||||
},
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.name = this.$store.state.i.name || '';
|
|
||||||
this.location = this.$store.state.i.profile.location;
|
|
||||||
this.description = this.$store.state.i.description;
|
|
||||||
this.birthday = this.$store.state.i.profile.birthday;
|
|
||||||
this.isCat = this.$store.state.i.isCat;
|
|
||||||
this.isBot = this.$store.state.i.isBot;
|
|
||||||
this.isLocked = this.$store.state.i.isLocked;
|
|
||||||
this.carefulBot = this.$store.state.i.carefulBot;
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
updateAvatar() {
|
|
||||||
(this as any).apis.updateAvatar();
|
|
||||||
},
|
|
||||||
save(notify) {
|
|
||||||
(this as any).api('i/update', {
|
|
||||||
name: this.name || null,
|
|
||||||
location: this.location || null,
|
|
||||||
description: this.description || null,
|
|
||||||
birthday: this.birthday || null,
|
|
||||||
isCat: this.isCat,
|
|
||||||
isBot: this.isBot,
|
|
||||||
isLocked: this.isLocked,
|
|
||||||
carefulBot: this.carefulBot
|
|
||||||
}).then(() => {
|
|
||||||
if (notify) {
|
|
||||||
(this as any).apis.notify('%i18n:@profile-updated%');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
|
||||||
.profile
|
|
||||||
> .avatar
|
|
||||||
> img
|
|
||||||
display inline-block
|
|
||||||
vertical-align top
|
|
||||||
width 64px
|
|
||||||
height 64px
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
> button
|
|
||||||
margin-left 8px
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -2,38 +2,59 @@
|
||||||
<div class="mk-settings">
|
<div class="mk-settings">
|
||||||
<div class="nav">
|
<div class="nav">
|
||||||
<p :class="{ active: page == 'profile' }" @mousedown="page = 'profile'">%fa:user .fw%%i18n:@profile%</p>
|
<p :class="{ active: page == 'profile' }" @mousedown="page = 'profile'">%fa:user .fw%%i18n:@profile%</p>
|
||||||
|
<p :class="{ active: page == 'theme' }" @mousedown="page = 'theme'">%fa:palette .fw%%i18n:@theme%</p>
|
||||||
<p :class="{ active: page == 'web' }" @mousedown="page = 'web'">%fa:desktop .fw%Web</p>
|
<p :class="{ active: page == 'web' }" @mousedown="page = 'web'">%fa:desktop .fw%Web</p>
|
||||||
<p :class="{ active: page == 'notification' }" @mousedown="page = 'notification'">%fa:R bell .fw%%i18n:@notification%</p>
|
<p :class="{ active: page == 'notification' }" @mousedown="page = 'notification'">%fa:R bell .fw%%i18n:@notification%</p>
|
||||||
<p :class="{ active: page == 'drive' }" @mousedown="page = 'drive'">%fa:cloud .fw%%i18n:@drive%</p>
|
<p :class="{ active: page == 'drive' }" @mousedown="page = 'drive'">%fa:cloud .fw%%i18n:@drive%</p>
|
||||||
<p :class="{ active: page == 'hashtags' }" @mousedown="page = 'hashtags'">%fa:hashtag .fw%%i18n:@tags%</p>
|
<p :class="{ active: page == 'hashtags' }" @mousedown="page = 'hashtags'">%fa:hashtag .fw%%i18n:@tags%</p>
|
||||||
<p :class="{ active: page == 'mute' }" @mousedown="page = 'mute'">%fa:ban .fw%%i18n:@mute%</p>
|
<p :class="{ active: page == 'mute' }" @mousedown="page = 'mute'">%fa:ban .fw%%i18n:@mute%</p>
|
||||||
<p :class="{ active: page == 'apps' }" @mousedown="page = 'apps'">%fa:puzzle-piece .fw%%i18n:@apps%</p>
|
<p :class="{ active: page == 'apps' }" @mousedown="page = 'apps'">%fa:puzzle-piece .fw%%i18n:@apps%</p>
|
||||||
<p :class="{ active: page == 'twitter' }" @mousedown="page = 'twitter'">%fa:B twitter .fw%Twitter</p>
|
|
||||||
<p :class="{ active: page == 'security' }" @mousedown="page = 'security'">%fa:unlock-alt .fw%%i18n:@security%</p>
|
<p :class="{ active: page == 'security' }" @mousedown="page = 'security'">%fa:unlock-alt .fw%%i18n:@security%</p>
|
||||||
<p :class="{ active: page == 'api' }" @mousedown="page = 'api'">%fa:key .fw%API</p>
|
<p :class="{ active: page == 'api' }" @mousedown="page = 'api'">%fa:key .fw%API</p>
|
||||||
<p :class="{ active: page == 'other' }" @mousedown="page = 'other'">%fa:cogs .fw%%i18n:@other%</p>
|
<p :class="{ active: page == 'other' }" @mousedown="page = 'other'">%fa:cogs .fw%%i18n:@other%</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="pages">
|
<div class="pages">
|
||||||
<section class="profile" v-show="page == 'profile'">
|
<div class="profile" v-show="page == 'profile'">
|
||||||
<h1>%i18n:@profile%</h1>
|
<mk-profile-editor/>
|
||||||
<x-profile/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="web" v-show="page == 'web'">
|
<ui-card>
|
||||||
<h1>%i18n:@theme%</h1>
|
<div slot="title">%fa:B twitter% %i18n:@twitter%</div>
|
||||||
<mk-theme/>
|
<section>
|
||||||
</section>
|
<mk-twitter-setting/>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
</div>
|
||||||
|
|
||||||
<section class="web" v-show="page == 'web'">
|
<ui-card class="theme" v-show="page == 'theme'">
|
||||||
<h1>%i18n:@behaviour%</h1>
|
<div slot="title">%fa:palette% %i18n:@theme%</div>
|
||||||
<ui-switch v-model="fetchOnScroll">
|
|
||||||
%i18n:@fetch-on-scroll%
|
<section>
|
||||||
<span slot="desc">%i18n:@fetch-on-scroll-desc%</span>
|
<mk-theme/>
|
||||||
</ui-switch>
|
</section>
|
||||||
<ui-switch v-model="autoPopout">
|
</ui-card>
|
||||||
%i18n:@auto-popout%
|
|
||||||
<span slot="desc">%i18n:@auto-popout-desc%</span>
|
<ui-card class="web" v-show="page == 'web'">
|
||||||
</ui-switch>
|
<div slot="title">%fa:sliders-h% %i18n:@behaviour%</div>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<ui-switch v-model="fetchOnScroll">
|
||||||
|
%i18n:@fetch-on-scroll%
|
||||||
|
<span slot="desc">%i18n:@fetch-on-scroll-desc%</span>
|
||||||
|
</ui-switch>
|
||||||
|
<ui-switch v-model="autoPopout">
|
||||||
|
%i18n:@auto-popout%
|
||||||
|
<span slot="desc">%i18n:@auto-popout-desc%</span>
|
||||||
|
</ui-switch>
|
||||||
|
<ui-switch v-model="deckNav">%i18n:@deck-nav%<span slot="desc">%i18n:@deck-nav-desc%</span></ui-switch>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>%i18n:@advanced%</summary>
|
||||||
|
<ui-switch v-model="apiViaStream">
|
||||||
|
%i18n:@api-via-stream%
|
||||||
|
<span slot="desc">%i18n:@api-via-stream-desc%</span>
|
||||||
|
</ui-switch>
|
||||||
|
</details>
|
||||||
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<header>%i18n:@note-visibility%</header>
|
<header>%i18n:@note-visibility%</header>
|
||||||
|
@ -49,24 +70,26 @@
|
||||||
</ui-select>
|
</ui-select>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
<details>
|
<ui-card class="web" v-show="page == 'web'">
|
||||||
<summary>%i18n:@advanced%</summary>
|
<div slot="title">%fa:desktop% %i18n:@display%</div>
|
||||||
<ui-switch v-model="apiViaStream">
|
|
||||||
%i18n:@api-via-stream%
|
|
||||||
<span slot="desc">%i18n:@api-via-stream-desc%</span>
|
|
||||||
</ui-switch>
|
|
||||||
</details>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="web" v-show="page == 'web'">
|
<section>
|
||||||
<h1>%i18n:@display%</h1>
|
<ui-button @click="customizeHome">%i18n:@customize%</ui-button>
|
||||||
<div class="div">
|
</section>
|
||||||
<button class="ui button" @click="customizeHome" style="margin-bottom: 16px">%i18n:@customize%</button>
|
<section>
|
||||||
</div>
|
<header>%i18n:@wallpaper%</header>
|
||||||
<div class="div">
|
<ui-button @click="updateWallpaper">%i18n:@choose-wallpaper%</ui-button>
|
||||||
<button class="ui" @click="updateWallpaper">%i18n:@choose-wallpaper%</button>
|
<ui-button @click="deleteWallpaper">%i18n:@delete-wallpaper%</ui-button>
|
||||||
<button class="ui" @click="deleteWallpaper">%i18n:@delete-wallpaper%</button>
|
</section>
|
||||||
|
<section>
|
||||||
|
<header>%i18n:@navbar-position%</header>
|
||||||
|
<ui-radio v-model="navbar" value="top">%i18n:@navbar-position-top%</ui-radio>
|
||||||
|
<ui-radio v-model="navbar" value="left">%i18n:@navbar-position-left%</ui-radio>
|
||||||
|
<ui-radio v-model="navbar" value="right">%i18n:@navbar-position-right%</ui-radio>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
<ui-switch v-model="darkmode">%i18n:@dark-mode%</ui-switch>
|
<ui-switch v-model="darkmode">%i18n:@dark-mode%</ui-switch>
|
||||||
<ui-switch v-model="useShadow">%i18n:@use-shadow%</ui-switch>
|
<ui-switch v-model="useShadow">%i18n:@use-shadow%</ui-switch>
|
||||||
<ui-switch v-model="roundedCorners">%i18n:@rounded-corners%</ui-switch>
|
<ui-switch v-model="roundedCorners">%i18n:@rounded-corners%</ui-switch>
|
||||||
|
@ -75,171 +98,186 @@
|
||||||
<ui-switch v-model="contrastedAcct">%i18n:@contrasted-acct%</ui-switch>
|
<ui-switch v-model="contrastedAcct">%i18n:@contrasted-acct%</ui-switch>
|
||||||
<ui-switch v-model="showFullAcct">%i18n:common.show-full-acct%</ui-switch>
|
<ui-switch v-model="showFullAcct">%i18n:common.show-full-acct%</ui-switch>
|
||||||
<ui-switch v-model="iLikeSushi">%i18n:common.i-like-sushi%</ui-switch>
|
<ui-switch v-model="iLikeSushi">%i18n:common.i-like-sushi%</ui-switch>
|
||||||
</div>
|
</section>
|
||||||
<ui-switch v-model="showPostFormOnTopOfTl">%i18n:@post-form-on-timeline%</ui-switch>
|
<section>
|
||||||
<ui-switch v-model="suggestRecentHashtags">%i18n:@suggest-recent-hashtags%</ui-switch>
|
<ui-switch v-model="showPostFormOnTopOfTl">%i18n:@post-form-on-timeline%</ui-switch>
|
||||||
<ui-switch v-model="showClockOnHeader">%i18n:@show-clock-on-header%</ui-switch>
|
<ui-switch v-model="suggestRecentHashtags">%i18n:@suggest-recent-hashtags%</ui-switch>
|
||||||
<ui-switch v-model="alwaysShowNsfw">%i18n:common.always-show-nsfw%</ui-switch>
|
<ui-switch v-model="showClockOnHeader">%i18n:@show-clock-on-header%</ui-switch>
|
||||||
<ui-switch v-model="showReplyTarget">%i18n:@show-reply-target%</ui-switch>
|
<ui-switch v-model="alwaysShowNsfw">%i18n:common.always-show-nsfw%</ui-switch>
|
||||||
<ui-switch v-model="showMyRenotes">%i18n:@show-my-renotes%</ui-switch>
|
<ui-switch v-model="showReplyTarget">%i18n:@show-reply-target%</ui-switch>
|
||||||
<ui-switch v-model="showRenotedMyNotes">%i18n:@show-renoted-my-notes%</ui-switch>
|
<ui-switch v-model="showMyRenotes">%i18n:@show-my-renotes%</ui-switch>
|
||||||
<ui-switch v-model="showLocalRenotes">%i18n:@show-local-renotes%</ui-switch>
|
<ui-switch v-model="showRenotedMyNotes">%i18n:@show-renoted-my-notes%</ui-switch>
|
||||||
<ui-switch v-model="showMaps">%i18n:@show-maps%</ui-switch>
|
<ui-switch v-model="showLocalRenotes">%i18n:@show-local-renotes%</ui-switch>
|
||||||
<ui-switch v-model="disableAnimatedMfm">%i18n:common.disable-animated-mfm%</ui-switch>
|
<ui-switch v-model="showMaps">%i18n:@show-maps%</ui-switch>
|
||||||
<ui-switch v-model="games_reversi_showBoardLabels">%i18n:common.show-reversi-board-labels%</ui-switch>
|
<ui-switch v-model="disableAnimatedMfm">%i18n:common.disable-animated-mfm%</ui-switch>
|
||||||
<ui-switch v-model="games_reversi_useContrastStones">%i18n:common.use-contrast-reversi-stones%</ui-switch>
|
<ui-switch v-model="games_reversi_showBoardLabels">%i18n:common.show-reversi-board-labels%</ui-switch>
|
||||||
|
<ui-switch v-model="games_reversi_useContrastStones">%i18n:common.use-contrast-reversi-stones%</ui-switch>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="web" v-show="page == 'web'">
|
||||||
|
<div slot="title">%fa:volume-up% %i18n:@sound%</div>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<header>%i18n:@navbar-position%</header>
|
<ui-switch v-model="enableSounds">
|
||||||
<ui-radio v-model="navbar" value="top">%i18n:@navbar-position-top%</ui-radio>
|
%i18n:@enable-sounds%
|
||||||
<ui-radio v-model="navbar" value="left">%i18n:@navbar-position-left%</ui-radio>
|
<span slot="desc">%i18n:@enable-sounds-desc%</span>
|
||||||
<ui-radio v-model="navbar" value="right">%i18n:@navbar-position-right%</ui-radio>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="web" v-show="page == 'web'">
|
|
||||||
<h1>%i18n:@sound%</h1>
|
|
||||||
<ui-switch v-model="enableSounds">
|
|
||||||
%i18n:@enable-sounds%
|
|
||||||
<span slot="desc">%i18n:@enable-sounds-desc%</span>
|
|
||||||
</ui-switch>
|
|
||||||
<label>%i18n:@volume%</label>
|
|
||||||
<input type="range"
|
|
||||||
v-model="soundVolume"
|
|
||||||
:disabled="!enableSounds"
|
|
||||||
max="1"
|
|
||||||
step="0.1"
|
|
||||||
/>
|
|
||||||
<button class="ui button" @click="soundTest">%fa:volume-up% %i18n:@test%</button>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="web" v-show="page == 'web'">
|
|
||||||
<h1>%i18n:@mobile%</h1>
|
|
||||||
<ui-switch v-model="disableViaMobile">%i18n:@disable-via-mobile%</ui-switch>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="web" v-show="page == 'web'">
|
|
||||||
<h1>%i18n:@language%</h1>
|
|
||||||
<select v-model="lang" placeholder="%i18n:@pick-language%">
|
|
||||||
<optgroup label="%i18n:@recommended%">
|
|
||||||
<option value="">%i18n:@auto%</option>
|
|
||||||
</optgroup>
|
|
||||||
|
|
||||||
<optgroup label="%i18n:@specify-language%">
|
|
||||||
<option v-for="x in langs" :value="x[0]" :key="x[0]">{{ x[1] }}</option>
|
|
||||||
</optgroup>
|
|
||||||
</select>
|
|
||||||
<div class="none ui info">
|
|
||||||
<p>%fa:info-circle%%i18n:@language-desc%</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="web" v-show="page == 'web'">
|
|
||||||
<h1>%i18n:@cache%</h1>
|
|
||||||
<button class="ui button" @click="clean">%i18n:@clean-cache%</button>
|
|
||||||
<div class="none ui info warn">
|
|
||||||
<p>%fa:exclamation-triangle%%i18n:@cache-warn%</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="notification" v-show="page == 'notification'">
|
|
||||||
<h1>%i18n:@notification%</h1>
|
|
||||||
<ui-switch v-model="$store.state.i.settings.autoWatch" @change="onChangeAutoWatch">
|
|
||||||
%i18n:@auto-watch%
|
|
||||||
<span slot="desc">%i18n:@auto-watch-desc%</span>
|
|
||||||
</ui-switch>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="drive" v-show="page == 'drive'">
|
|
||||||
<h1>%i18n:@drive%</h1>
|
|
||||||
<x-drive/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="hashtags" v-show="page == 'hashtags'">
|
|
||||||
<h1>%i18n:@tags%</h1>
|
|
||||||
<x-tags/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="mute" v-show="page == 'mute'">
|
|
||||||
<h1>%i18n:@mute%</h1>
|
|
||||||
<x-mute/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="apps" v-show="page == 'apps'">
|
|
||||||
<h1>%i18n:@apps%</h1>
|
|
||||||
<x-apps/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="twitter" v-show="page == 'twitter'">
|
|
||||||
<h1>Twitter</h1>
|
|
||||||
<mk-twitter-setting/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="password" v-show="page == 'security'">
|
|
||||||
<h1>%i18n:@password%</h1>
|
|
||||||
<x-password/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="2fa" v-show="page == 'security'">
|
|
||||||
<h1>%i18n:@2fa%</h1>
|
|
||||||
<x-2fa/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="signin" v-show="page == 'security'">
|
|
||||||
<h1>%i18n:@signin%</h1>
|
|
||||||
<x-signins/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="api" v-show="page == 'api'">
|
|
||||||
<h1>API</h1>
|
|
||||||
<x-api/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="other" v-show="page == 'other'">
|
|
||||||
<h1>%i18n:@about%</h1>
|
|
||||||
<p v-if="meta">%i18n:@operator%: <i><a :href="meta.maintainer.url" target="_blank">{{ meta.maintainer.name }}</a></i></p>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section class="other" v-show="page == 'other'">
|
|
||||||
<h1>%i18n:@update%</h1>
|
|
||||||
<p>
|
|
||||||
<span>%i18n:@version% <i>{{ version }}</i></span>
|
|
||||||
<template v-if="latestVersion !== undefined">
|
|
||||||
<br>
|
|
||||||
<span>%i18n:@latest-version% <i>{{ latestVersion ? latestVersion : version }}</i></span>
|
|
||||||
</template>
|
|
||||||
</p>
|
|
||||||
<button class="ui button block" @click="checkForUpdate" :disabled="checkingForUpdate">
|
|
||||||
<template v-if="checkingForUpdate">%i18n:@update-checking%<mk-ellipsis/></template>
|
|
||||||
<template v-else>%i18n:@do-update%</template>
|
|
||||||
</button>
|
|
||||||
<details>
|
|
||||||
<summary>%i18n:@update-settings%</summary>
|
|
||||||
<ui-switch v-model="preventUpdate">
|
|
||||||
%i18n:@prevent-update%
|
|
||||||
<span slot="desc">%i18n:@prevent-update-desc%</span>
|
|
||||||
</ui-switch>
|
</ui-switch>
|
||||||
</details>
|
<label>%i18n:@volume%</label>
|
||||||
</section>
|
<input type="range"
|
||||||
|
v-model="soundVolume"
|
||||||
|
:disabled="!enableSounds"
|
||||||
|
max="1"
|
||||||
|
step="0.1"
|
||||||
|
/>
|
||||||
|
<ui-button @click="soundTest">%fa:volume-up% %i18n:@test%</ui-button>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
<section class="other" v-show="page == 'other'">
|
<ui-card class="web" v-show="page == 'web'">
|
||||||
<h1>%i18n:@advanced-settings%</h1>
|
<div slot="title">%fa:language% %i18n:@language%</div>
|
||||||
<ui-switch v-model="debug">
|
<section class="fit-top">
|
||||||
%i18n:@debug-mode%
|
<ui-select v-model="lang" placeholder="%i18n:@pick-language%">
|
||||||
<span slot="desc">%i18n:@debug-mode-desc%</span>
|
<optgroup label="%i18n:@recommended%">
|
||||||
</ui-switch>
|
<option value="">%i18n:@auto%</option>
|
||||||
<ui-switch v-model="enableExperimentalFeatures">
|
</optgroup>
|
||||||
%i18n:@experimental%
|
|
||||||
<span slot="desc">%i18n:@experimental-desc%</span>
|
<optgroup label="%i18n:@specify-language%">
|
||||||
</ui-switch>
|
<option v-for="x in langs" :value="x[0]" :key="x[0]">{{ x[1] }}</option>
|
||||||
</section>
|
</optgroup>
|
||||||
|
</ui-select>
|
||||||
|
<div class="none ui info">
|
||||||
|
<p>%fa:info-circle%%i18n:@language-desc%</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="web" v-show="page == 'web'">
|
||||||
|
<div slot="title">%fa:trash-alt R% %i18n:@cache%</div>
|
||||||
|
<section>
|
||||||
|
<ui-button @click="clean">%i18n:@clean-cache%</ui-button>
|
||||||
|
<div class="none ui info warn">
|
||||||
|
<p>%fa:exclamation-triangle%%i18n:@cache-warn%</p>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="notification" v-show="page == 'notification'">
|
||||||
|
<div slot="title">%fa:bell R% %i18n:@notification%</div>
|
||||||
|
<section>
|
||||||
|
<ui-switch v-model="$store.state.i.settings.autoWatch" @change="onChangeAutoWatch">
|
||||||
|
%i18n:@auto-watch%
|
||||||
|
<span slot="desc">%i18n:@auto-watch-desc%</span>
|
||||||
|
</ui-switch>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="drive" v-show="page == 'drive'">
|
||||||
|
<div slot="title">%fa:cloud% %i18n:@drive%</div>
|
||||||
|
<section>
|
||||||
|
<x-drive/>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="hashtags" v-show="page == 'hashtags'">
|
||||||
|
<div slot="title">%fa:hashtag% %i18n:@tags%</div>
|
||||||
|
<section>
|
||||||
|
<x-tags/>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="mute" v-show="page == 'mute'">
|
||||||
|
<div slot="title">%fa:ban% %i18n:@mute%</div>
|
||||||
|
<section>
|
||||||
|
<x-mute/>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="apps" v-show="page == 'apps'">
|
||||||
|
<div slot="title">%fa:puzzle-piece% %i18n:@apps%</div>
|
||||||
|
<section>
|
||||||
|
<x-apps/>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="password" v-show="page == 'security'">
|
||||||
|
<div slot="title">%fa:unlock-alt% %i18n:@password%</div>
|
||||||
|
<section>
|
||||||
|
<x-password/>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="2fa" v-show="page == 'security'">
|
||||||
|
<div slot="title">%fa:mobile-alt% %i18n:@2fa%</div>
|
||||||
|
<section>
|
||||||
|
<x-2fa/>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="signin" v-show="page == 'security'">
|
||||||
|
<div slot="title">%fa:sign-in-alt% %i18n:@signin%</div>
|
||||||
|
<section>
|
||||||
|
<x-signins/>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="api" v-show="page == 'api'">
|
||||||
|
<div slot="title">%fa:key% API</div>
|
||||||
|
<section class="fit-top">
|
||||||
|
<x-api/>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="other" v-show="page == 'other'">
|
||||||
|
<div slot="title">%fa:info-circle% %i18n:@about%</div>
|
||||||
|
<section>
|
||||||
|
<p v-if="meta">%i18n:@operator%: <i><a :href="meta.maintainer.url" target="_blank">{{ meta.maintainer.name }}</a></i></p>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="other" v-show="page == 'other'">
|
||||||
|
<div slot="title">%fa:sync-alt% %i18n:@update%</div>
|
||||||
|
<section>
|
||||||
|
<p>
|
||||||
|
<span>%i18n:@version% <i>{{ version }}</i></span>
|
||||||
|
<template v-if="latestVersion !== undefined">
|
||||||
|
<br>
|
||||||
|
<span>%i18n:@latest-version% <i>{{ latestVersion ? latestVersion : version }}</i></span>
|
||||||
|
</template>
|
||||||
|
</p>
|
||||||
|
<button class="ui button block" @click="checkForUpdate" :disabled="checkingForUpdate">
|
||||||
|
<template v-if="checkingForUpdate">%i18n:@update-checking%<mk-ellipsis/></template>
|
||||||
|
<template v-else>%i18n:@do-update%</template>
|
||||||
|
</button>
|
||||||
|
<details>
|
||||||
|
<summary>%i18n:@update-settings%</summary>
|
||||||
|
<ui-switch v-model="preventUpdate">
|
||||||
|
%i18n:@prevent-update%
|
||||||
|
<span slot="desc">%i18n:@prevent-update-desc%</span>
|
||||||
|
</ui-switch>
|
||||||
|
</details>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
|
|
||||||
|
<ui-card class="other" v-show="page == 'other'">
|
||||||
|
<div slot="title">%fa:cogs% %i18n:@advanced-settings%</div>
|
||||||
|
<section>
|
||||||
|
<ui-switch v-model="debug">
|
||||||
|
%i18n:@debug-mode%
|
||||||
|
<span slot="desc">%i18n:@debug-mode-desc%</span>
|
||||||
|
</ui-switch>
|
||||||
|
<ui-switch v-model="enableExperimentalFeatures">
|
||||||
|
%i18n:@experimental%
|
||||||
|
<span slot="desc">%i18n:@experimental-desc%</span>
|
||||||
|
</ui-switch>
|
||||||
|
</section>
|
||||||
|
</ui-card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import XProfile from './settings.profile.vue';
|
|
||||||
import XMute from './settings.mute.vue';
|
import XMute from './settings.mute.vue';
|
||||||
import XPassword from './settings.password.vue';
|
import XPassword from './settings.password.vue';
|
||||||
import X2fa from './settings.2fa.vue';
|
import X2fa from './settings.2fa.vue';
|
||||||
|
@ -253,7 +291,6 @@ import checkForUpdate from '../../../common/scripts/check-for-update';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
XProfile,
|
|
||||||
XMute,
|
XMute,
|
||||||
XPassword,
|
XPassword,
|
||||||
X2fa,
|
X2fa,
|
||||||
|
@ -295,6 +332,11 @@ export default Vue.extend({
|
||||||
set(value) { this.$store.commit('device/set', { key: 'autoPopout', value }); }
|
set(value) { this.$store.commit('device/set', { key: 'autoPopout', value }); }
|
||||||
},
|
},
|
||||||
|
|
||||||
|
deckNav: {
|
||||||
|
get() { return this.$store.state.settings.deckNav; },
|
||||||
|
set(value) { this.$store.commit('settings/set', { key: 'deckNav', value }); }
|
||||||
|
},
|
||||||
|
|
||||||
darkmode: {
|
darkmode: {
|
||||||
get() { return this.$store.state.device.darkmode; },
|
get() { return this.$store.state.device.darkmode; },
|
||||||
set(value) { this.$store.commit('device/set', { key: 'darkmode', value }); }
|
set(value) { this.$store.commit('device/set', { key: 'darkmode', value }); }
|
||||||
|
@ -438,11 +480,6 @@ export default Vue.extend({
|
||||||
disableAnimatedMfm: {
|
disableAnimatedMfm: {
|
||||||
get() { return this.$store.state.settings.disableAnimatedMfm; },
|
get() { return this.$store.state.settings.disableAnimatedMfm; },
|
||||||
set(value) { this.$store.dispatch('settings/set', { key: 'disableAnimatedMfm', value }); }
|
set(value) { this.$store.dispatch('settings/set', { key: 'disableAnimatedMfm', value }); }
|
||||||
},
|
|
||||||
|
|
||||||
disableViaMobile: {
|
|
||||||
get() { return this.$store.state.settings.disableViaMobile; },
|
|
||||||
set(value) { this.$store.dispatch('settings/set', { key: 'disableViaMobile', value }); }
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -546,34 +583,10 @@ export default Vue.extend({
|
||||||
height 100%
|
height 100%
|
||||||
flex auto
|
flex auto
|
||||||
overflow auto
|
overflow auto
|
||||||
|
background var(--bg)
|
||||||
|
|
||||||
> section
|
> section
|
||||||
margin 32px
|
margin 32px
|
||||||
color var(--text)
|
color var(--text)
|
||||||
|
|
||||||
> h1
|
|
||||||
margin 0 0 1em 0
|
|
||||||
padding 0 0 8px 0
|
|
||||||
font-size 1em
|
|
||||||
border-bottom solid 1px var(--faceDivider)
|
|
||||||
|
|
||||||
&, >>> *
|
|
||||||
.ui.button.block
|
|
||||||
margin 16px 0
|
|
||||||
|
|
||||||
> section
|
|
||||||
margin 32px 0
|
|
||||||
|
|
||||||
> h2
|
|
||||||
margin 0 0 1em 0
|
|
||||||
padding 0 0 8px 0
|
|
||||||
font-size 1em
|
|
||||||
color var(--text)
|
|
||||||
border-bottom solid 1px var(--faceDivider)
|
|
||||||
|
|
||||||
> .web
|
|
||||||
> .div
|
|
||||||
border-bottom solid 1px var(--faceDivider)
|
|
||||||
margin 16px 0
|
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs" :class="{ naked, narrow, active, isStacked, draghover, dragging, dropready }"
|
<div class="dnpfarvgbnfmyzbdquhhzyxcmstpdqzs" :class="{ naked, narrow, active, isStacked, draghover, dragging, dropready }"
|
||||||
@dragover.prevent.stop="onDragover"
|
@dragover.prevent.stop="onDragover"
|
||||||
@dragenter.prevent="onDragenter"
|
|
||||||
@dragleave="onDragleave"
|
@dragleave="onDragleave"
|
||||||
@drop.prevent.stop="onDrop">
|
@drop.prevent.stop="onDrop">
|
||||||
<header :class="{ indicate: count > 0 }"
|
<header :class="{ indicate: count > 0 }"
|
||||||
|
@ -16,7 +15,8 @@
|
||||||
</button>
|
</button>
|
||||||
<slot name="header"></slot>
|
<slot name="header"></slot>
|
||||||
<span class="count" v-if="count > 0">({{ count }})</span>
|
<span class="count" v-if="count > 0">({{ count }})</span>
|
||||||
<button class="menu" ref="menu" @click.stop="showMenu">%fa:caret-down%</button>
|
<button v-if="!isTemporaryColumn" class="menu" ref="menu" @click.stop="showMenu">%fa:caret-down%</button>
|
||||||
|
<button v-else class="close" @click.stop="close">%fa:times%</button>
|
||||||
</header>
|
</header>
|
||||||
<div ref="body" v-show="active">
|
<div ref="body" v-show="active">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
@ -34,11 +34,13 @@ export default Vue.extend({
|
||||||
props: {
|
props: {
|
||||||
column: {
|
column: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true
|
required: false,
|
||||||
|
default: null
|
||||||
},
|
},
|
||||||
isStacked: {
|
isStacked: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true
|
required: false,
|
||||||
|
default: false
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
|
@ -61,6 +63,12 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
isTemporaryColumn(): boolean {
|
||||||
|
return this.column == null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
inject: {
|
inject: {
|
||||||
getColumnVm: { from: 'getColumnVm' }
|
getColumnVm: { from: 'getColumnVm' }
|
||||||
},
|
},
|
||||||
|
@ -96,14 +104,20 @@ export default Vue.extend({
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$refs.body.addEventListener('scroll', this.onScroll, { passive: true });
|
this.$refs.body.addEventListener('scroll', this.onScroll, { passive: true });
|
||||||
this.$root.$on('deck.column.dragStart', this.onOtherDragStart);
|
|
||||||
this.$root.$on('deck.column.dragEnd', this.onOtherDragEnd);
|
if (!this.isTemporaryColumn) {
|
||||||
|
this.$root.$on('deck.column.dragStart', this.onOtherDragStart);
|
||||||
|
this.$root.$on('deck.column.dragEnd', this.onOtherDragEnd);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.$refs.body.removeEventListener('scroll', this.onScroll);
|
this.$refs.body.removeEventListener('scroll', this.onScroll);
|
||||||
this.$root.$off('deck.column.dragStart', this.onOtherDragStart);
|
|
||||||
this.$root.$off('deck.column.dragEnd', this.onOtherDragEnd);
|
if (!this.isTemporaryColumn) {
|
||||||
|
this.$root.$off('deck.column.dragStart', this.onOtherDragStart);
|
||||||
|
this.$root.$off('deck.column.dragEnd', this.onOtherDragEnd);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -203,6 +217,7 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
onContextmenu(e) {
|
onContextmenu(e) {
|
||||||
|
if (this.isTemporaryColumn) return;
|
||||||
contextmenu((this as any).os)(e, this.getMenu());
|
contextmenu((this as any).os)(e, this.getMenu());
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -214,6 +229,13 @@ export default Vue.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.$store.commit('device/set', {
|
||||||
|
key: 'deckTemporaryColumn',
|
||||||
|
value: null
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
goTop() {
|
goTop() {
|
||||||
this.$refs.body.scrollTo({
|
this.$refs.body.scrollTo({
|
||||||
top: 0,
|
top: 0,
|
||||||
|
@ -222,6 +244,12 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
onDragstart(e) {
|
onDragstart(e) {
|
||||||
|
// テンポラリカラムはドラッグさせない
|
||||||
|
if (this.isTemporaryColumn) {
|
||||||
|
e.preventDefault();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
e.dataTransfer.effectAllowed = 'move';
|
e.dataTransfer.effectAllowed = 'move';
|
||||||
e.dataTransfer.setData('mk-deck-column', this.column.id);
|
e.dataTransfer.setData('mk-deck-column', this.column.id);
|
||||||
this.dragging = true;
|
this.dragging = true;
|
||||||
|
@ -232,6 +260,12 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
onDragover(e) {
|
onDragover(e) {
|
||||||
|
// テンポラリカラムにはドロップさせない
|
||||||
|
if (this.isTemporaryColumn) {
|
||||||
|
e.dataTransfer.dropEffect = 'none';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 自分自身がドラッグされている場合
|
// 自分自身がドラッグされている場合
|
||||||
if (this.dragging) {
|
if (this.dragging) {
|
||||||
// 自分自身にはドロップさせない
|
// 自分自身にはドロップさせない
|
||||||
|
@ -242,9 +276,7 @@ export default Vue.extend({
|
||||||
const isDeckColumn = e.dataTransfer.types[0] == 'mk-deck-column';
|
const isDeckColumn = e.dataTransfer.types[0] == 'mk-deck-column';
|
||||||
|
|
||||||
e.dataTransfer.dropEffect = isDeckColumn ? 'move' : 'none';
|
e.dataTransfer.dropEffect = isDeckColumn ? 'move' : 'none';
|
||||||
},
|
|
||||||
|
|
||||||
onDragenter() {
|
|
||||||
if (!this.dragging) this.draghover = true;
|
if (!this.dragging) this.draghover = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -349,6 +381,7 @@ export default Vue.extend({
|
||||||
|
|
||||||
> .toggleActive
|
> .toggleActive
|
||||||
> .menu
|
> .menu
|
||||||
|
> .close
|
||||||
padding 0
|
padding 0
|
||||||
width $header-height
|
width $header-height
|
||||||
line-height $header-height
|
line-height $header-height
|
||||||
|
@ -365,6 +398,7 @@ export default Vue.extend({
|
||||||
margin-left -16px
|
margin-left -16px
|
||||||
|
|
||||||
> .menu
|
> .menu
|
||||||
|
> .close
|
||||||
margin-left auto
|
margin-left auto
|
||||||
margin-right -16px
|
margin-right -16px
|
||||||
|
|
||||||
|
|
69
src/client/app/desktop/views/pages/deck/deck.note-column.vue
Normal file
69
src/client/app/desktop/views/pages/deck/deck.note-column.vue
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
<template>
|
||||||
|
<x-column>
|
||||||
|
<span slot="header">
|
||||||
|
%fa:comment-alt R%<span>{{ title }}</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="rvtscbadixhhbsczoorqoaygovdeecsx" v-if="note">
|
||||||
|
<div class="is-remote" v-if="note.user.host != null">%fa:exclamation-triangle% %i18n:@is-remote%<a :href="note.url || note.uri" target="_blank">%i18n:@view-remote%</a></div>
|
||||||
|
<x-note :note="note" :detail="true" :mini="true"/>
|
||||||
|
</div>
|
||||||
|
</x-column>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import XColumn from './deck.column.vue';
|
||||||
|
import XNotes from './deck.notes.vue';
|
||||||
|
import XNote from '../../components/note.vue';
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
components: {
|
||||||
|
XColumn,
|
||||||
|
XNotes,
|
||||||
|
XNote
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
noteId: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
note: null,
|
||||||
|
fetching: true
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
title(): string {
|
||||||
|
return this.note ? Vue.filter('userName')(this.note.user) : '';
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
(this as any).api('notes/show', { noteId: this.noteId }).then(note => {
|
||||||
|
this.note = note;
|
||||||
|
this.fetching = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.rvtscbadixhhbsczoorqoaygovdeecsx
|
||||||
|
> .is-remote
|
||||||
|
padding 8px 16px
|
||||||
|
font-size 12px
|
||||||
|
|
||||||
|
&.is-remote
|
||||||
|
color var(--remoteInfoFg)
|
||||||
|
background var(--remoteInfoBg)
|
||||||
|
|
||||||
|
> a
|
||||||
|
font-weight bold
|
||||||
|
|
||||||
|
</style>
|
|
@ -1,71 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="fnlfosztlhtptnongximhlbykxblytcq">
|
|
||||||
<mk-avatar class="avatar" :user="note.user"/>
|
|
||||||
<div class="main">
|
|
||||||
<mk-note-header class="header" :note="note" :mini="true"/>
|
|
||||||
<div class="body">
|
|
||||||
<mk-sub-note-content class="text" :note="note"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import Vue from 'vue';
|
|
||||||
|
|
||||||
export default Vue.extend({
|
|
||||||
props: {
|
|
||||||
note: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
// TODO
|
|
||||||
truncate: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
|
||||||
.fnlfosztlhtptnongximhlbykxblytcq
|
|
||||||
display flex
|
|
||||||
padding 16px
|
|
||||||
font-size 10px
|
|
||||||
background var(--subNoteBg)
|
|
||||||
|
|
||||||
&.smart
|
|
||||||
> .main
|
|
||||||
width 100%
|
|
||||||
|
|
||||||
> header
|
|
||||||
align-items center
|
|
||||||
|
|
||||||
> .avatar
|
|
||||||
flex-shrink 0
|
|
||||||
display block
|
|
||||||
margin 0 8px 0 0
|
|
||||||
width 38px
|
|
||||||
height 38px
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
> .main
|
|
||||||
flex 1
|
|
||||||
min-width 0
|
|
||||||
|
|
||||||
> .header
|
|
||||||
margin-bottom 2px
|
|
||||||
|
|
||||||
> .body
|
|
||||||
|
|
||||||
> .text
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
color var(--subNoteText)
|
|
||||||
|
|
||||||
pre
|
|
||||||
max-height 120px
|
|
||||||
font-size 80%
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -1,323 +0,0 @@
|
||||||
<template>
|
|
||||||
<div
|
|
||||||
v-if="!mediaView"
|
|
||||||
v-show="appearNote.deletedAt == null"
|
|
||||||
:tabindex="appearNote.deletedAt == null ? '-1' : null"
|
|
||||||
class="zyjjkidcqjnlegkqebitfviomuqmseqk"
|
|
||||||
:class="{ renote: isRenote }"
|
|
||||||
v-hotkey="keymap"
|
|
||||||
:title="title"
|
|
||||||
>
|
|
||||||
<div class="reply-to" v-if="appearNote.reply && (!$store.getters.isSignedIn || $store.state.settings.showReplyTarget)">
|
|
||||||
<x-sub :note="appearNote.reply"/>
|
|
||||||
</div>
|
|
||||||
<div class="renote" v-if="isRenote">
|
|
||||||
<mk-avatar class="avatar" :user="note.user"/>
|
|
||||||
%fa:retweet%
|
|
||||||
<span>{{ '%i18n:@reposted-by%'.substr(0, '%i18n:@reposted-by%'.indexOf('{')) }}</span>
|
|
||||||
<router-link class="name" :to="note.user | userPage">{{ note.user | userName }}</router-link>
|
|
||||||
<span>{{ '%i18n:@reposted-by%'.substr('%i18n:@reposted-by%'.indexOf('}') + 1) }}</span>
|
|
||||||
<mk-time :time="note.createdAt"/>
|
|
||||||
</div>
|
|
||||||
<article>
|
|
||||||
<mk-avatar class="avatar" :user="appearNote.user"/>
|
|
||||||
<div class="main">
|
|
||||||
<mk-note-header class="header" :note="appearNote" :mini="true"/>
|
|
||||||
<div class="body">
|
|
||||||
<p v-if="appearNote.cw != null" class="cw">
|
|
||||||
<span class="text" v-if="appearNote.cw != ''">{{ appearNote.cw }}</span>
|
|
||||||
<mk-cw-button v-model="showContent"/>
|
|
||||||
</p>
|
|
||||||
<div class="content" v-show="appearNote.cw == null || showContent">
|
|
||||||
<div class="text">
|
|
||||||
<span v-if="appearNote.isHidden" style="opacity: 0.5">(%i18n:@private%)</span>
|
|
||||||
<a class="reply" v-if="appearNote.reply">%fa:reply%</a>
|
|
||||||
<misskey-flavored-markdown v-if="appearNote.text" :text="appearNote.text" :i="$store.state.i"/>
|
|
||||||
<a class="rp" v-if="appearNote.renote != null">RP:</a>
|
|
||||||
</div>
|
|
||||||
<div class="files" v-if="appearNote.files.length > 0">
|
|
||||||
<mk-media-list :media-list="appearNote.files"/>
|
|
||||||
</div>
|
|
||||||
<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:map-marker-alt% %i18n:@location%</a>
|
|
||||||
<div class="renote" v-if="appearNote.renote">
|
|
||||||
<mk-note-preview :note="appearNote.renote" :mini="true"/>
|
|
||||||
</div>
|
|
||||||
<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="false" :mini="true"/>
|
|
||||||
</div>
|
|
||||||
<span class="app" v-if="appearNote.app">via <b>{{ appearNote.app.name }}</b></span>
|
|
||||||
</div>
|
|
||||||
<footer>
|
|
||||||
<mk-reactions-viewer :note="appearNote" ref="reactionsViewer"/>
|
|
||||||
<button @click="reply()">
|
|
||||||
<template v-if="appearNote.reply">%fa:reply-all%</template>
|
|
||||||
<template v-else>%fa:reply%</template>
|
|
||||||
</button>
|
|
||||||
<button @click="renote()" title="Renote">%fa:retweet%</button>
|
|
||||||
<button :class="{ reacted: appearNote.myReaction != null }" @click="react()" ref="reactButton">%fa:plus%</button>
|
|
||||||
<button class="menu" @click="menu()" ref="menuButton">%fa:ellipsis-h%</button>
|
|
||||||
</footer>
|
|
||||||
</div>
|
|
||||||
</article>
|
|
||||||
</div>
|
|
||||||
<div v-else class="srwrkujossgfuhrbnvqkybtzxpblgchi">
|
|
||||||
<div v-if="note.files.length > 0">
|
|
||||||
<mk-media-list :media-list="note.files"/>
|
|
||||||
</div>
|
|
||||||
<div v-if="note.renote && note.renote.files.length > 0">
|
|
||||||
<mk-media-list :media-list="note.renote.files"/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import Vue from 'vue';
|
|
||||||
import MkPostFormWindow from '../../components/post-form-window.vue';
|
|
||||||
import MkRenoteFormWindow from '../../components/renote-form-window.vue';
|
|
||||||
import XSub from './deck.note.sub.vue';
|
|
||||||
import noteMixin from '../../../../common/scripts/note-mixin';
|
|
||||||
import noteSubscriber from '../../../../common/scripts/note-subscriber';
|
|
||||||
|
|
||||||
export default Vue.extend({
|
|
||||||
components: {
|
|
||||||
XSub
|
|
||||||
},
|
|
||||||
|
|
||||||
mixins: [
|
|
||||||
noteMixin(),
|
|
||||||
noteSubscriber('note')
|
|
||||||
],
|
|
||||||
|
|
||||||
props: {
|
|
||||||
note: {
|
|
||||||
type: Object,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
mediaView: {
|
|
||||||
type: Boolean,
|
|
||||||
required: false,
|
|
||||||
default: false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="stylus" scoped>
|
|
||||||
.srwrkujossgfuhrbnvqkybtzxpblgchi
|
|
||||||
font-size 13px
|
|
||||||
margin 4px 12px
|
|
||||||
|
|
||||||
&:first-child
|
|
||||||
margin-top 12px
|
|
||||||
|
|
||||||
&:last-child
|
|
||||||
margin-bottom 12px
|
|
||||||
|
|
||||||
.zyjjkidcqjnlegkqebitfviomuqmseqk
|
|
||||||
font-size 13px
|
|
||||||
border-bottom solid 1px 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
|
|
||||||
border-bottom none
|
|
||||||
|
|
||||||
&.smart
|
|
||||||
> article
|
|
||||||
> .main
|
|
||||||
> header
|
|
||||||
align-items center
|
|
||||||
margin-bottom 4px
|
|
||||||
|
|
||||||
> .renote
|
|
||||||
display flex
|
|
||||||
align-items center
|
|
||||||
padding 8px 16px 0 16px
|
|
||||||
line-height 28px
|
|
||||||
white-space pre
|
|
||||||
color var(--renoteText)
|
|
||||||
background linear-gradient(to bottom, var(--renoteGradient) 0%, var(--face) 100%)
|
|
||||||
|
|
||||||
.avatar
|
|
||||||
flex-shrink 0
|
|
||||||
display inline-block
|
|
||||||
width 20px
|
|
||||||
height 20px
|
|
||||||
margin 0 8px 0 0
|
|
||||||
border-radius 6px
|
|
||||||
|
|
||||||
[data-fa]
|
|
||||||
margin-right 4px
|
|
||||||
|
|
||||||
> span
|
|
||||||
flex-shrink 0
|
|
||||||
|
|
||||||
&:last-of-type
|
|
||||||
margin-right 8px
|
|
||||||
|
|
||||||
.name
|
|
||||||
overflow hidden
|
|
||||||
flex-shrink 1
|
|
||||||
text-overflow ellipsis
|
|
||||||
white-space nowrap
|
|
||||||
font-weight bold
|
|
||||||
|
|
||||||
> .mk-time
|
|
||||||
display block
|
|
||||||
margin-left auto
|
|
||||||
flex-shrink 0
|
|
||||||
font-size 0.9em
|
|
||||||
|
|
||||||
& + article
|
|
||||||
padding-top 8px
|
|
||||||
|
|
||||||
> article
|
|
||||||
display flex
|
|
||||||
padding 16px 16px 4px
|
|
||||||
|
|
||||||
> .avatar
|
|
||||||
flex-shrink 0
|
|
||||||
display block
|
|
||||||
margin 0 10px 8px 0
|
|
||||||
width 42px
|
|
||||||
height 42px
|
|
||||||
border-radius 6px
|
|
||||||
//position -webkit-sticky
|
|
||||||
//position sticky
|
|
||||||
//top 62px
|
|
||||||
|
|
||||||
> .main
|
|
||||||
flex 1
|
|
||||||
min-width 0
|
|
||||||
|
|
||||||
> .body
|
|
||||||
|
|
||||||
> .cw
|
|
||||||
cursor default
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
overflow-wrap break-word
|
|
||||||
color var(--noteText)
|
|
||||||
|
|
||||||
> .text
|
|
||||||
margin-right 8px
|
|
||||||
|
|
||||||
> .content
|
|
||||||
|
|
||||||
> .text
|
|
||||||
display block
|
|
||||||
margin 0
|
|
||||||
padding 0
|
|
||||||
overflow-wrap break-word
|
|
||||||
color var(--noteText)
|
|
||||||
|
|
||||||
>>> .title
|
|
||||||
display block
|
|
||||||
margin-bottom 4px
|
|
||||||
padding 4px
|
|
||||||
font-size 90%
|
|
||||||
text-align center
|
|
||||||
background var(--mfmTitleBg)
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
>>> .code
|
|
||||||
margin 8px 0
|
|
||||||
|
|
||||||
>>> .quote
|
|
||||||
margin 8px
|
|
||||||
padding 6px 12px
|
|
||||||
color var(--mfmQuote)
|
|
||||||
border-left solid 3px var(--mfmQuoteLine)
|
|
||||||
|
|
||||||
> .reply
|
|
||||||
margin-right 8px
|
|
||||||
color var(--noteText)
|
|
||||||
|
|
||||||
> .rp
|
|
||||||
margin-left 4px
|
|
||||||
font-style oblique
|
|
||||||
color var(--renoteText)
|
|
||||||
|
|
||||||
[data-is-me]:after
|
|
||||||
content "you"
|
|
||||||
padding 0 4px
|
|
||||||
margin-left 4px
|
|
||||||
font-size 80%
|
|
||||||
color var(--primaryForeground)
|
|
||||||
background var(--primary)
|
|
||||||
border-radius 4px
|
|
||||||
|
|
||||||
.mk-url-preview
|
|
||||||
margin-top 8px
|
|
||||||
|
|
||||||
> .files
|
|
||||||
> img
|
|
||||||
display block
|
|
||||||
max-width 100%
|
|
||||||
|
|
||||||
> .location
|
|
||||||
margin 4px 0
|
|
||||||
font-size 12px
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
> .map
|
|
||||||
width 100%
|
|
||||||
height 200px
|
|
||||||
|
|
||||||
&:empty
|
|
||||||
display none
|
|
||||||
|
|
||||||
> .mk-poll
|
|
||||||
font-size 80%
|
|
||||||
|
|
||||||
> .renote
|
|
||||||
margin 8px 0
|
|
||||||
|
|
||||||
> *
|
|
||||||
padding 16px
|
|
||||||
border dashed 1px var(--quoteBorder)
|
|
||||||
border-radius 8px
|
|
||||||
|
|
||||||
> .app
|
|
||||||
font-size 12px
|
|
||||||
color #ccc
|
|
||||||
|
|
||||||
> footer
|
|
||||||
> button
|
|
||||||
margin 0
|
|
||||||
padding 4px 8px 8px 8px
|
|
||||||
background transparent
|
|
||||||
border none
|
|
||||||
box-shadow none
|
|
||||||
font-size 1em
|
|
||||||
color var(--noteActions)
|
|
||||||
cursor pointer
|
|
||||||
|
|
||||||
&:not(:last-child)
|
|
||||||
margin-right 28px
|
|
||||||
|
|
||||||
&:hover
|
|
||||||
color var(--noteActionsHover)
|
|
||||||
|
|
||||||
> .count
|
|
||||||
display inline
|
|
||||||
margin 0 0 0 8px
|
|
||||||
color #999
|
|
||||||
|
|
||||||
&.reacted
|
|
||||||
color var(--primary)
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -17,7 +17,7 @@
|
||||||
<!--<transition-group name="mk-notes" class="transition">-->
|
<!--<transition-group name="mk-notes" class="transition">-->
|
||||||
<div class="notes">
|
<div class="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)" :media-view="mediaView"/>
|
<x-note :note="note" :key="note.id" @update:note="onNoteUpdated(i, $event)" :media-view="mediaView" :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:angle-up%{{ note._datetext }}</span>
|
<span>%fa:angle-up%{{ note._datetext }}</span>
|
||||||
<span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span>
|
<span>%fa:angle-down%{{ _notes[i + 1]._datetext }}</span>
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
|
||||||
import XNote from './deck.note.vue';
|
import XNote from '../../components/note.vue';
|
||||||
|
|
||||||
const displayLimit = 20;
|
const displayLimit = 20;
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ export default Vue.extend({
|
||||||
display block
|
display block
|
||||||
margin 0
|
margin 0
|
||||||
line-height 32px
|
line-height 32px
|
||||||
font-size 14px
|
font-size 12px
|
||||||
text-align center
|
text-align center
|
||||||
color var(--dateDividerFg)
|
color var(--dateDividerFg)
|
||||||
background var(--dateDividerBg)
|
background var(--dateDividerBg)
|
||||||
|
|
|
@ -66,15 +66,15 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="notification.type == 'quote'">
|
<template v-if="notification.type == 'quote'">
|
||||||
<x-note :note="notification.note" @update:note="onNoteUpdated"/>
|
<x-note :note="notification.note" @update:note="onNoteUpdated" :mini="true"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="notification.type == 'reply'">
|
<template v-if="notification.type == 'reply'">
|
||||||
<x-note :note="notification.note" @update:note="onNoteUpdated"/>
|
<x-note :note="notification.note" @update:note="onNoteUpdated" :mini="true"/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template v-if="notification.type == 'mention'">
|
<template v-if="notification.type == 'mention'">
|
||||||
<x-note :note="notification.note" @update:note="onNoteUpdated"/>
|
<x-note :note="notification.note" @update:note="onNoteUpdated" :mini="true"/>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import getNoteSummary from '../../../../../../misc/get-note-summary';
|
import getNoteSummary from '../../../../../../misc/get-note-summary';
|
||||||
import XNote from './deck.note.vue';
|
import XNote from '../../components/note.vue';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
|
|
261
src/client/app/desktop/views/pages/deck/deck.user-column.vue
Normal file
261
src/client/app/desktop/views/pages/deck/deck.user-column.vue
Normal file
|
@ -0,0 +1,261 @@
|
||||||
|
<template>
|
||||||
|
<x-column>
|
||||||
|
<span slot="header">
|
||||||
|
%fa:user%<span>{{ title }}</span>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<div class="zubukjlciycdsyynicqrnlsmdwmymzqu" v-if="user">
|
||||||
|
<div class="is-remote" v-if="user.host != null">%fa:exclamation-triangle% %i18n:@is-remote%<a :href="user.url || user.uri" target="_blank">%i18n:@view-remote%</a></div>
|
||||||
|
<header :style="bannerStyle">
|
||||||
|
<div>
|
||||||
|
<mk-follow-button v-if="$store.getters.isSignedIn && user.id != $store.state.i.id" :user="user" class="follow"/>
|
||||||
|
<mk-avatar class="avatar" :user="user" :disable-preview="true"/>
|
||||||
|
<span class="name">{{ user | userName }}</span>
|
||||||
|
<span class="acct">@{{ user | acct }}</span>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<div class="info">
|
||||||
|
<div class="description">
|
||||||
|
<misskey-flavored-markdown v-if="user.description" :text="user.description" :i="$store.state.i"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="pinned" v-if="user.pinnedNotes && user.pinnedNotes.length > 0">
|
||||||
|
<p>%fa:thumbtack% %i18n:@pinned-notes%</p>
|
||||||
|
<div class="notes">
|
||||||
|
<x-note v-for="n in user.pinnedNotes" :key="n.id" :note="n" :mini="true"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="images" v-if="images.length > 0">
|
||||||
|
<router-link v-for="image in images" :style="`background-image: url(${image.thumbnailUrl})`" :key="`${image.id}:${image._note.id}`" :to="image._note | notePage"></router-link>
|
||||||
|
</div>
|
||||||
|
<div class="tl">
|
||||||
|
<x-notes ref="timeline" :more="existMore ? fetchMoreNotes : null"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</x-column>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import Vue from 'vue';
|
||||||
|
import parseAcct from '../../../../../../misc/acct/parse';
|
||||||
|
import XColumn from './deck.column.vue';
|
||||||
|
import XNotes from './deck.notes.vue';
|
||||||
|
import XNote from '../../components/note.vue';
|
||||||
|
|
||||||
|
const fetchLimit = 10;
|
||||||
|
|
||||||
|
export default Vue.extend({
|
||||||
|
components: {
|
||||||
|
XColumn,
|
||||||
|
XNotes,
|
||||||
|
XNote
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
acct: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
user: null,
|
||||||
|
fetching: true,
|
||||||
|
existMore: false,
|
||||||
|
moreFetching: false,
|
||||||
|
withFiles: false,
|
||||||
|
images: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
title(): string {
|
||||||
|
return this.user ? Vue.filter('userName')(this.user) : '';
|
||||||
|
},
|
||||||
|
|
||||||
|
bannerStyle(): any {
|
||||||
|
if (this.user == null) return {};
|
||||||
|
if (this.user.bannerUrl == null) return {};
|
||||||
|
return {
|
||||||
|
backgroundColor: this.user.bannerColor && this.user.bannerColor.length == 3 ? `rgb(${ this.user.bannerColor.join(',') })` : null,
|
||||||
|
backgroundImage: `url(${ this.user.bannerUrl })`
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
created() {
|
||||||
|
(this as any).api('users/show', parseAcct(this.acct)).then(user => {
|
||||||
|
this.user = user;
|
||||||
|
this.fetching = false;
|
||||||
|
|
||||||
|
this.$nextTick(() => {
|
||||||
|
(this.$refs.timeline as any).init(() => this.initTl());
|
||||||
|
});
|
||||||
|
|
||||||
|
(this as any).api('users/notes', {
|
||||||
|
userId: this.user.id,
|
||||||
|
withFiles: true,
|
||||||
|
limit: 9
|
||||||
|
}).then(notes => {
|
||||||
|
notes.forEach(note => {
|
||||||
|
note.files.forEach(file => {
|
||||||
|
file._note = note;
|
||||||
|
if (this.images.length < 9) this.images.push(file);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
initTl() {
|
||||||
|
return new Promise((res, rej) => {
|
||||||
|
(this as any).api('users/notes', {
|
||||||
|
userId: this.user.id,
|
||||||
|
limit: fetchLimit + 1,
|
||||||
|
withFiles: this.withFiles,
|
||||||
|
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
||||||
|
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
|
||||||
|
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
|
||||||
|
}).then(notes => {
|
||||||
|
if (notes.length == fetchLimit + 1) {
|
||||||
|
notes.pop();
|
||||||
|
this.existMore = true;
|
||||||
|
}
|
||||||
|
res(notes);
|
||||||
|
}, rej);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
fetchMoreNotes() {
|
||||||
|
this.moreFetching = true;
|
||||||
|
|
||||||
|
const promise = (this as any).api('users/notes', {
|
||||||
|
userId: this.user.id,
|
||||||
|
limit: fetchLimit + 1,
|
||||||
|
untilId: (this.$refs.timeline as any).tail().id,
|
||||||
|
withFiles: this.withFiles,
|
||||||
|
includeMyRenotes: this.$store.state.settings.showMyRenotes,
|
||||||
|
includeRenotedMyNotes: this.$store.state.settings.showRenotedMyNotes,
|
||||||
|
includeLocalRenotes: this.$store.state.settings.showLocalRenotes
|
||||||
|
});
|
||||||
|
|
||||||
|
promise.then(notes => {
|
||||||
|
if (notes.length == fetchLimit + 1) {
|
||||||
|
notes.pop();
|
||||||
|
} else {
|
||||||
|
this.existMore = false;
|
||||||
|
}
|
||||||
|
notes.forEach(n => (this.$refs.timeline as any).append(n));
|
||||||
|
this.moreFetching = false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="stylus" scoped>
|
||||||
|
.zubukjlciycdsyynicqrnlsmdwmymzqu
|
||||||
|
background var(--deckUserColumnBg)
|
||||||
|
|
||||||
|
> .is-remote
|
||||||
|
padding 8px 16px
|
||||||
|
font-size 12px
|
||||||
|
|
||||||
|
&.is-remote
|
||||||
|
color var(--remoteInfoFg)
|
||||||
|
background var(--remoteInfoBg)
|
||||||
|
|
||||||
|
> a
|
||||||
|
font-weight bold
|
||||||
|
|
||||||
|
> header
|
||||||
|
overflow hidden
|
||||||
|
background-size cover
|
||||||
|
background-position center
|
||||||
|
|
||||||
|
> div
|
||||||
|
padding 32px
|
||||||
|
background rgba(#000, 0.5)
|
||||||
|
color #fff
|
||||||
|
text-align center
|
||||||
|
|
||||||
|
> .follow
|
||||||
|
position absolute
|
||||||
|
top 16px
|
||||||
|
right 16px
|
||||||
|
|
||||||
|
> .avatar
|
||||||
|
display block
|
||||||
|
width 64px
|
||||||
|
height 64px
|
||||||
|
margin 0 auto
|
||||||
|
|
||||||
|
> .name
|
||||||
|
display block
|
||||||
|
margin-top 8px
|
||||||
|
font-weight bold
|
||||||
|
text-shadow 0 0 8px #000
|
||||||
|
|
||||||
|
> .acct
|
||||||
|
font-size 14px
|
||||||
|
opacity 0.7
|
||||||
|
text-shadow 0 0 8px #000
|
||||||
|
|
||||||
|
> .info
|
||||||
|
padding 16px
|
||||||
|
font-size 14px
|
||||||
|
color var(--text)
|
||||||
|
text-align center
|
||||||
|
background var(--face)
|
||||||
|
border-bottom solid 1px var(--faceDivider)
|
||||||
|
|
||||||
|
&:before
|
||||||
|
content ""
|
||||||
|
display blcok
|
||||||
|
position absolute
|
||||||
|
top -32px
|
||||||
|
left 0
|
||||||
|
right 0
|
||||||
|
width 0px
|
||||||
|
margin 0 auto
|
||||||
|
border-top solid 16px transparent
|
||||||
|
border-left solid 16px transparent
|
||||||
|
border-right solid 16px transparent
|
||||||
|
border-bottom solid 16px var(--face)
|
||||||
|
|
||||||
|
> .pinned
|
||||||
|
padding-bottom 16px
|
||||||
|
background var(--deckUserColumnBg)
|
||||||
|
|
||||||
|
> p
|
||||||
|
margin 0
|
||||||
|
padding 8px 16px
|
||||||
|
font-size 14px
|
||||||
|
color var(--text)
|
||||||
|
|
||||||
|
> .notes
|
||||||
|
background var(--face)
|
||||||
|
|
||||||
|
> .images
|
||||||
|
display grid
|
||||||
|
grid-template-rows 1fr 1fr 1fr
|
||||||
|
grid-template-columns 1fr 1fr 1fr
|
||||||
|
gap 4px
|
||||||
|
height 250px
|
||||||
|
padding 16px
|
||||||
|
margin-bottom 16px
|
||||||
|
background var(--face)
|
||||||
|
|
||||||
|
> *
|
||||||
|
background-position center center
|
||||||
|
background-size cover
|
||||||
|
background-clip content-box
|
||||||
|
|
||||||
|
> .tl
|
||||||
|
background var(--face)
|
||||||
|
|
||||||
|
</style>
|
|
@ -9,6 +9,10 @@
|
||||||
</div>
|
</div>
|
||||||
<x-column-core v-else :ref="ids[0]" :key="ids[0]" :column="columns.find(c => c.id == ids[0])"/>
|
<x-column-core v-else :ref="ids[0]" :key="ids[0]" :column="columns.find(c => c.id == ids[0])"/>
|
||||||
</template>
|
</template>
|
||||||
|
<template v-if="temporaryColumn">
|
||||||
|
<x-user-column v-if="temporaryColumn.type == 'user'" :acct="temporaryColumn.acct" :key="temporaryColumn.acct"/>
|
||||||
|
<x-note-column v-else-if="temporaryColumn.type == 'note'" :note-id="temporaryColumn.noteId" :key="temporaryColumn.noteId"/>
|
||||||
|
</template>
|
||||||
<button ref="add" @click="add" title="%i18n:common.deck.add-column%">%fa:plus%</button>
|
<button ref="add" @click="add" title="%i18n:common.deck.add-column%">%fa:plus%</button>
|
||||||
</div>
|
</div>
|
||||||
</mk-ui>
|
</mk-ui>
|
||||||
|
@ -19,11 +23,16 @@ import Vue from 'vue';
|
||||||
import XColumnCore from './deck.column-core.vue';
|
import XColumnCore from './deck.column-core.vue';
|
||||||
import Menu from '../../../../common/views/components/menu.vue';
|
import Menu from '../../../../common/views/components/menu.vue';
|
||||||
import MkUserListsWindow from '../../components/user-lists-window.vue';
|
import MkUserListsWindow from '../../components/user-lists-window.vue';
|
||||||
|
import XUserColumn from './deck.user-column.vue';
|
||||||
|
import XNoteColumn from './deck.note-column.vue';
|
||||||
|
|
||||||
import * as uuid from 'uuid';
|
import * as uuid from 'uuid';
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
components: {
|
||||||
XColumnCore
|
XColumnCore,
|
||||||
|
XUserColumn,
|
||||||
|
XNoteColumn
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -31,15 +40,21 @@ export default Vue.extend({
|
||||||
if (this.$store.state.settings.deck == null) return [];
|
if (this.$store.state.settings.deck == null) return [];
|
||||||
return this.$store.state.settings.deck.columns;
|
return this.$store.state.settings.deck.columns;
|
||||||
},
|
},
|
||||||
|
|
||||||
layout(): any[] {
|
layout(): any[] {
|
||||||
if (this.$store.state.settings.deck == null) return [];
|
if (this.$store.state.settings.deck == null) return [];
|
||||||
if (this.$store.state.settings.deck.layout == null) return this.$store.state.settings.deck.columns.map(c => [c.id]);
|
if (this.$store.state.settings.deck.layout == null) return this.$store.state.settings.deck.columns.map(c => [c.id]);
|
||||||
return this.$store.state.settings.deck.layout;
|
return this.$store.state.settings.deck.layout;
|
||||||
},
|
},
|
||||||
|
|
||||||
style(): any {
|
style(): any {
|
||||||
return {
|
return {
|
||||||
height: `calc(100vh - ${this.$store.state.uiHeaderHeight}px)`
|
height: `calc(100vh - ${this.$store.state.uiHeaderHeight}px)`
|
||||||
};
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
temporaryColumn(): any {
|
||||||
|
return this.$store.state.device.deckTemporaryColumn;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -50,6 +65,8 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
|
this.$store.commit('navHook', this.onNav);
|
||||||
|
|
||||||
if (this.$store.state.settings.deck == null) {
|
if (this.$store.state.settings.deck == null) {
|
||||||
const deck = {
|
const deck = {
|
||||||
columns: [/*{
|
columns: [/*{
|
||||||
|
@ -95,6 +112,8 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
|
this.$store.commit('navHook', null);
|
||||||
|
|
||||||
document.documentElement.style.overflow = 'auto';
|
document.documentElement.style.overflow = 'auto';
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -103,6 +122,30 @@ export default Vue.extend({
|
||||||
return this.$refs[id][0];
|
return this.$refs[id][0];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onNav(to) {
|
||||||
|
if (!this.$store.state.settings.deckNav) return false;
|
||||||
|
|
||||||
|
if (to.name == 'user') {
|
||||||
|
this.$store.commit('device/set', {
|
||||||
|
key: 'deckTemporaryColumn',
|
||||||
|
value: {
|
||||||
|
type: 'user',
|
||||||
|
acct: to.params.user
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
} else if (to.name == 'note') {
|
||||||
|
this.$store.commit('device/set', {
|
||||||
|
key: 'deckTemporaryColumn',
|
||||||
|
value: {
|
||||||
|
type: 'note',
|
||||||
|
noteId: to.params.note
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
add() {
|
add() {
|
||||||
this.os.new(Menu, {
|
this.os.new(Menu, {
|
||||||
source: this.$refs.add,
|
source: this.$refs.add,
|
||||||
|
|
|
@ -60,9 +60,6 @@ export default Vue.extend({
|
||||||
margin-right 4px
|
margin-right 4px
|
||||||
|
|
||||||
> .stream
|
> .stream
|
||||||
display -webkit-flex
|
|
||||||
display -moz-flex
|
|
||||||
display -ms-flex
|
|
||||||
display flex
|
display flex
|
||||||
justify-content center
|
justify-content center
|
||||||
flex-wrap wrap
|
flex-wrap wrap
|
||||||
|
|
|
@ -148,6 +148,19 @@ export default (callback: (launch: (router: VueRouter, api?: (os: MiOS) => API)
|
||||||
});
|
});
|
||||||
//#endregion
|
//#endregion
|
||||||
|
|
||||||
|
// Navigation hook
|
||||||
|
router.beforeEach((to, from, next) => {
|
||||||
|
if (os.store.state.navHook) {
|
||||||
|
if (os.store.state.navHook(to)) {
|
||||||
|
next(false);
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
next();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
Vue.mixin({
|
Vue.mixin({
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
<div class="signin-as" v-html="'%i18n:@signed-in-as%'.replace('{}', `<b>${name}</b>`)"></div>
|
<div class="signin-as" v-html="'%i18n:@signed-in-as%'.replace('{}', `<b>${name}</b>`)"></div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<x-profile/>
|
<mk-profile-editor/>
|
||||||
|
|
||||||
<ui-card>
|
<ui-card>
|
||||||
<div slot="title">%fa:palette% %i18n:@theme%</div>
|
<div slot="title">%fa:palette% %i18n:@theme%</div>
|
||||||
|
@ -148,13 +148,7 @@ import Vue from 'vue';
|
||||||
import { apiUrl, version, codename, langs } from '../../../config';
|
import { apiUrl, version, codename, langs } from '../../../config';
|
||||||
import checkForUpdate from '../../../common/scripts/check-for-update';
|
import checkForUpdate from '../../../common/scripts/check-for-update';
|
||||||
|
|
||||||
import XProfile from './settings/settings.profile.vue';
|
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
components: {
|
|
||||||
XProfile
|
|
||||||
},
|
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
apiUrl,
|
apiUrl,
|
||||||
|
|
|
@ -10,6 +10,7 @@ const defaultSettings = {
|
||||||
home: null,
|
home: null,
|
||||||
mobileHome: [],
|
mobileHome: [],
|
||||||
deck: null,
|
deck: null,
|
||||||
|
deckNav: true,
|
||||||
tagTimelines: [],
|
tagTimelines: [],
|
||||||
fetchOnScroll: true,
|
fetchOnScroll: true,
|
||||||
showMaps: true,
|
showMaps: true,
|
||||||
|
@ -57,7 +58,8 @@ const defaultDeviceSettings = {
|
||||||
alwaysShowNsfw: false,
|
alwaysShowNsfw: false,
|
||||||
postStyle: 'standard',
|
postStyle: 'standard',
|
||||||
navbar: 'top',
|
navbar: 'top',
|
||||||
mobileNotificationPosition: 'bottom'
|
mobileNotificationPosition: 'bottom',
|
||||||
|
deckTemporaryColumn: null
|
||||||
};
|
};
|
||||||
|
|
||||||
export default (os: MiOS) => new Vuex.Store({
|
export default (os: MiOS) => new Vuex.Store({
|
||||||
|
@ -68,7 +70,8 @@ export default (os: MiOS) => new Vuex.Store({
|
||||||
state: {
|
state: {
|
||||||
i: null,
|
i: null,
|
||||||
indicate: false,
|
indicate: false,
|
||||||
uiHeaderHeight: 0
|
uiHeaderHeight: 0,
|
||||||
|
navHook: null
|
||||||
},
|
},
|
||||||
|
|
||||||
getters: {
|
getters: {
|
||||||
|
@ -90,6 +93,10 @@ export default (os: MiOS) => new Vuex.Store({
|
||||||
|
|
||||||
setUiHeaderHeight(state, height) {
|
setUiHeaderHeight(state, height) {
|
||||||
state.uiHeaderHeight = height;
|
state.uiHeaderHeight = height;
|
||||||
|
},
|
||||||
|
|
||||||
|
navHook(state, callback) {
|
||||||
|
state.navHook = callback;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -174,6 +174,7 @@
|
||||||
desktopSettingsNavItemHover: ':lighten<10<$text',
|
desktopSettingsNavItemHover: ':lighten<10<$text',
|
||||||
|
|
||||||
deckAcrylicColumnBg: 'rgba(0, 0, 0, 0.25)',
|
deckAcrylicColumnBg: 'rgba(0, 0, 0, 0.25)',
|
||||||
|
deckUserColumnBg: ':darken<3<@face',
|
||||||
|
|
||||||
mobileHeaderBg: ':lighten<5<$secondary',
|
mobileHeaderBg: ':lighten<5<$secondary',
|
||||||
mobileHeaderFg: '$text',
|
mobileHeaderFg: '$text',
|
||||||
|
|
|
@ -174,6 +174,7 @@
|
||||||
desktopSettingsNavItemHover: ':darken<10<$text',
|
desktopSettingsNavItemHover: ':darken<10<$text',
|
||||||
|
|
||||||
deckAcrylicColumnBg: 'rgba(0, 0, 0, 0.1)',
|
deckAcrylicColumnBg: 'rgba(0, 0, 0, 0.1)',
|
||||||
|
deckUserColumnBg: ':darken<4<@face',
|
||||||
|
|
||||||
mobileHeaderBg: ':lighten<5<$secondary',
|
mobileHeaderBg: ':lighten<5<$secondary',
|
||||||
mobileHeaderFg: '$text',
|
mobileHeaderFg: '$text',
|
||||||
|
|
Loading…
Reference in a new issue