@@ -1,6 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
<svg :viewBox="`0 0 ${ viewBoxX } ${ viewBoxY }`" @mousedown.prevent="onMousedown">
 | 
			
		||||
	<title>%i18n:@total%<br/>%i18n:@notes%<br/>%i18n:@replies%<br/>%i18n:@renotes%</title>
 | 
			
		||||
	<title>{{ $t('total') }}<br/>{{ $t('notes') }}<br/>{{ $t('replies') }}<br/>{{ $t('renotes') }}</title>
 | 
			
		||||
	<polyline
 | 
			
		||||
		:points="pointsNote"
 | 
			
		||||
		fill="none"
 | 
			
		||||
@@ -27,6 +27,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
function dragListen(fn) {
 | 
			
		||||
	window.addEventListener('mousemove',  fn);
 | 
			
		||||
@@ -41,6 +42,7 @@ function dragClear(fn) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/activity.chart.vue'),
 | 
			
		||||
	props: ['data'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,10 +1,10 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-activity">
 | 
			
		||||
	<mk-widget-container :show-header="design == 0" :naked="design == 2">
 | 
			
		||||
		<template slot="header"><fa icon="chart-bar"/>%i18n:@title%</template>
 | 
			
		||||
		<button slot="func" title="%i18n:@toggle%" @click="toggle"><fa icon="sort"/></button>
 | 
			
		||||
		<template slot="header"><fa icon="chart-bar"/>{{ $t('title') }}</template>
 | 
			
		||||
		<button slot="func" :title="$t('toggle')" @click="toggle"><fa icon="sort"/></button>
 | 
			
		||||
 | 
			
		||||
		<p :class="$style.fetching" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>%i18n:common.loading%<mk-ellipsis/></p>
 | 
			
		||||
		<p :class="$style.fetching" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p>
 | 
			
		||||
		<template v-else>
 | 
			
		||||
			<x-calendar v-show="view == 0" :data="[].concat(activity)"/>
 | 
			
		||||
			<x-chart v-show="view == 1" :data="[].concat(activity)"/>
 | 
			
		||||
@@ -15,10 +15,12 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import XCalendar from './activity.calendar.vue';
 | 
			
		||||
import XChart from './activity.chart.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/activity.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		XCalendar,
 | 
			
		||||
		XChart
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-calendar" :data-melt="design == 4 || design == 5">
 | 
			
		||||
	<template v-if="design == 0 || design == 1">
 | 
			
		||||
		<button @click="prev" title="%i18n:@prev%"><fa icon="chevron-circle-left"/></button>
 | 
			
		||||
		<p class="title">{{ '%i18n:@title%'.replace('{1}', year).replace('{2}', month) }}</p>
 | 
			
		||||
		<button @click="next" title="%i18n:@next%"><fa icon="chevron-circle-right"/></button>
 | 
			
		||||
		<button @click="prev" :title="$t('prev')"><fa icon="chevron-circle-left"/></button>
 | 
			
		||||
		<p class="title">{{ $t('title', { year, month }) }}</p>
 | 
			
		||||
		<button @click="next" :title="$t('next')"><fa icon="chevron-circle-right"/></button>
 | 
			
		||||
	</template>
 | 
			
		||||
 | 
			
		||||
	<div class="calendar">
 | 
			
		||||
@@ -21,7 +21,7 @@
 | 
			
		||||
			:data-is-out-of-range="isOutOfRange(i + 1)"
 | 
			
		||||
			:data-is-donichi="isDonichi(i + 1)"
 | 
			
		||||
			@click="go(i + 1)"
 | 
			
		||||
			:title="isOutOfRange(i + 1) ? null : '%i18n:@go%'"
 | 
			
		||||
			:title="isOutOfRange(i + 1) ? null : $t('go')"
 | 
			
		||||
		>
 | 
			
		||||
			<div>{{ i + 1 }}</div>
 | 
			
		||||
		</div>
 | 
			
		||||
@@ -31,6 +31,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
const eachMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
 | 
			
		||||
 | 
			
		||||
@@ -39,6 +40,7 @@ function isLeapYear(year) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/calendar.vue'),
 | 
			
		||||
	props: {
 | 
			
		||||
		design: {
 | 
			
		||||
			default: 0
 | 
			
		||||
@@ -55,13 +57,13 @@ export default Vue.extend({
 | 
			
		||||
			month: new Date().getMonth() + 1,
 | 
			
		||||
			selected: new Date(),
 | 
			
		||||
			weekdayText: [
 | 
			
		||||
				'%i18n:common.weekday-short.sunday%',
 | 
			
		||||
				'%i18n:common.weekday-short.monday%',
 | 
			
		||||
				'%i18n:common.weekday-short.tuesday%',
 | 
			
		||||
				'%i18n:common.weekday-short.wednesday%',
 | 
			
		||||
				'%i18n:common.weekday-short.thursday%',
 | 
			
		||||
				'%i18n:common.weekday-short.friday%',
 | 
			
		||||
				'%i18n:common.weekday-short.saturday%'
 | 
			
		||||
				this.$t('@.weekday-short.sunday'),
 | 
			
		||||
				this.$t('@.weekday-short.monday'),
 | 
			
		||||
				this.$t('@.weekday-short.tuesday'),
 | 
			
		||||
				this.$t('@.weekday-short.wednesday'),
 | 
			
		||||
				this.$t('@.weekday-short.thursday'),
 | 
			
		||||
				this.$t('@.weekday-short.friday'),
 | 
			
		||||
				this.$t('@.weekday-short.saturday')
 | 
			
		||||
			]
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
<mk-window ref="window" is-modal width="800px" height="500px" @closed="destroyDom">
 | 
			
		||||
	<span slot="header">
 | 
			
		||||
		<span v-html="title" :class="$style.title"></span>
 | 
			
		||||
		<span :class="$style.count" v-if="multiple && files.length > 0">({{ files.length }}%i18n:@choose-file%)</span>
 | 
			
		||||
		<span :class="$style.count" v-if="multiple && files.length > 0">({{ $t('chosen-files', { count: files.length }) }})</span>
 | 
			
		||||
	</span>
 | 
			
		||||
 | 
			
		||||
	<mk-drive
 | 
			
		||||
@@ -13,22 +13,24 @@
 | 
			
		||||
		@change-selection="onChangeSelection"
 | 
			
		||||
	/>
 | 
			
		||||
	<div :class="$style.footer">
 | 
			
		||||
		<button :class="$style.upload" title="%i18n:@upload%" @click="upload"><fa icon="upload"/></button>
 | 
			
		||||
		<button :class="$style.cancel" @click="cancel">%i18n:@cancel%</button>
 | 
			
		||||
		<button :class="$style.ok" :disabled="multiple && files.length == 0" @click="ok">%i18n:@ok%</button>
 | 
			
		||||
		<button :class="$style.upload" :title="$t('title')" @click="upload"><fa icon="upload"/></button>
 | 
			
		||||
		<button :class="$style.cancel" @click="cancel">{{ $t('cancel') }}</button>
 | 
			
		||||
		<button :class="$style.ok" :disabled="multiple && files.length == 0" @click="ok">{{ $t('ok') }}</button>
 | 
			
		||||
	</div>
 | 
			
		||||
</mk-window>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/choose-file-from-drive-window.vue'),
 | 
			
		||||
	props: {
 | 
			
		||||
		multiple: {
 | 
			
		||||
			default: false
 | 
			
		||||
		},
 | 
			
		||||
		title: {
 | 
			
		||||
			default: '<fa :icon="['far', 'file']"/>%i18n:@choose-prompt%'
 | 
			
		||||
			default: () => this.$t('choose-prompt')
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	data() {
 | 
			
		||||
@@ -59,8 +61,6 @@ export default Vue.extend({
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" module>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.title
 | 
			
		||||
	> [data-icon]
 | 
			
		||||
		margin-right 4px
 | 
			
		||||
 
 | 
			
		||||
@@ -10,18 +10,20 @@
 | 
			
		||||
		:multiple="false"
 | 
			
		||||
	/>
 | 
			
		||||
	<div :class="$style.footer">
 | 
			
		||||
		<button :class="$style.cancel" @click="cancel">%i18n:@cancel%</button>
 | 
			
		||||
		<button :class="$style.ok" @click="ok">%i18n:@ok%</button>
 | 
			
		||||
		<button :class="$style.cancel" @click="cancel">{{ $t('cancel') }}</button>
 | 
			
		||||
		<button :class="$style.ok" @click="ok">{{ $t('ok') }}</button>
 | 
			
		||||
	</div>
 | 
			
		||||
</mk-window>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/choose-folder-from-drive-window.vue'),
 | 
			
		||||
	props: {
 | 
			
		||||
		title: {
 | 
			
		||||
			default: '<fa :icon="['far', 'folder']"/>%i18n:@choose-prompt%'
 | 
			
		||||
			default: () => this.$t('choose-prompt')
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
 
 | 
			
		||||
@@ -10,18 +10,20 @@
 | 
			
		||||
			/>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div :class="$style.actions">
 | 
			
		||||
			<button :class="$style.skip" @click="skip">%i18n:@skip%</button>
 | 
			
		||||
			<button :class="$style.cancel" @click="cancel">%i18n:@cancel%</button>
 | 
			
		||||
			<button :class="$style.ok" @click="ok">%i18n:@ok%</button>
 | 
			
		||||
			<button :class="$style.skip" @click="skip">{{ $t('skip') }}</button>
 | 
			
		||||
			<button :class="$style.cancel" @click="cancel">{{ $t('cancel') }}</button>
 | 
			
		||||
			<button :class="$style.ok" @click="ok">{{ $t('ok') }}</button>
 | 
			
		||||
		</div>
 | 
			
		||||
	</mk-window>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import VueCropper from 'vue-cropperjs';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/crop-window.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		VueCropper
 | 
			
		||||
	},
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
<template>
 | 
			
		||||
<mk-window ref="window" @closed="destroyDom" width="800px" height="500px" :popout-url="popout">
 | 
			
		||||
	<template slot="header">
 | 
			
		||||
		<p v-if="usage" :class="$style.info"><b>{{ usage.toFixed(1) }}%</b> %i18n:@used%</p>
 | 
			
		||||
		<span :class="$style.title"><fa icon="cloud"/>%i18n:common.drive%</span>
 | 
			
		||||
		<p v-if="usage" :class="$style.info"><b>{{ usage.toFixed(1) }}%</b> {{ $t('used') }}</p>
 | 
			
		||||
		<span :class="$style.title"><fa icon="cloud"/>{{ $t('@.drive') }}</span>
 | 
			
		||||
	</template>
 | 
			
		||||
	<mk-drive :class="$style.browser" multiple :init-folder="folder" ref="browser"/>
 | 
			
		||||
</mk-window>
 | 
			
		||||
@@ -10,9 +10,11 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import { url } from '../../../config';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/drive-window.vue'),
 | 
			
		||||
	props: ['folder'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
 
 | 
			
		||||
@@ -11,15 +11,15 @@
 | 
			
		||||
>
 | 
			
		||||
	<div class="label" v-if="$store.state.i.avatarId == file.id">
 | 
			
		||||
		<img src="/assets/label.svg"/>
 | 
			
		||||
		<p>%i18n:@avatar%</p>
 | 
			
		||||
		<p>{{ $t('avatar') }}</p>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="label" v-if="$store.state.i.bannerId == file.id">
 | 
			
		||||
		<img src="/assets/label.svg"/>
 | 
			
		||||
		<p>%i18n:@banner%</p>
 | 
			
		||||
		<p>{{ $t('banner') }}</p>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="label red" v-if="file.isSensitive">
 | 
			
		||||
		<img src="/assets/label-red.svg"/>
 | 
			
		||||
		<p>%i18n:@nsfw%</p>
 | 
			
		||||
		<p>{{ $t('nsfw') }}</p>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="thumbnail" ref="thumbnail" :style="`background-color: ${ background }`">
 | 
			
		||||
		<img :src="file.thumbnailUrl" alt="" @load="onThumbnailLoaded"/>
 | 
			
		||||
@@ -33,11 +33,13 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import * as anime from 'animejs';
 | 
			
		||||
import contextmenu from '../../api/contextmenu';
 | 
			
		||||
import copyToClipboard from '../../../common/scripts/copy-to-clipboard';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/drive.file.vue'),
 | 
			
		||||
	props: ['file'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
@@ -70,44 +72,44 @@ export default Vue.extend({
 | 
			
		||||
			this.isContextmenuShowing = true;
 | 
			
		||||
			contextmenu((this as any).os)(e, [{
 | 
			
		||||
				type: 'item',
 | 
			
		||||
				text: '%i18n:@contextmenu.rename%',
 | 
			
		||||
				text: this.$t('contextmenu.rename'),
 | 
			
		||||
				icon: 'i-cursor',
 | 
			
		||||
				action: this.rename
 | 
			
		||||
			}, {
 | 
			
		||||
				type: 'item',
 | 
			
		||||
				text: this.file.isSensitive ? '%i18n:@contextmenu.unmark-as-sensitive%' : '%i18n:@contextmenu.mark-as-sensitive%',
 | 
			
		||||
				text: this.file.isSensitive ? this.$t('contextmenu.unmark-as-sensitive') : this.$t('contextmenu.mark-as-sensitive'),
 | 
			
		||||
				icon: this.file.isSensitive ? ['far', 'eye'] : ['far', 'eye-slash'],
 | 
			
		||||
				action: this.toggleSensitive
 | 
			
		||||
			}, null, {
 | 
			
		||||
				type: 'item',
 | 
			
		||||
				text: '%i18n:@contextmenu.copy-url%',
 | 
			
		||||
				text: this.$t('contextmenu.copy-url'),
 | 
			
		||||
				icon: 'link',
 | 
			
		||||
				action: this.copyUrl
 | 
			
		||||
			}, {
 | 
			
		||||
				type: 'link',
 | 
			
		||||
				href: `${this.file.url}?download`,
 | 
			
		||||
				text: '%i18n:@contextmenu.download%',
 | 
			
		||||
				text: this.$t('contextmenu.download'),
 | 
			
		||||
				icon: 'download',
 | 
			
		||||
			}, null, {
 | 
			
		||||
				type: 'item',
 | 
			
		||||
				text: '%i18n:common.delete%',
 | 
			
		||||
				text: this.$t('@.delete'),
 | 
			
		||||
				icon: ['far', 'trash-alt'],
 | 
			
		||||
				action: this.deleteFile
 | 
			
		||||
			}, null, {
 | 
			
		||||
				type: 'nest',
 | 
			
		||||
				text: '%i18n:@contextmenu.else-files%',
 | 
			
		||||
				text: this.$t('contextmenu.else-files'),
 | 
			
		||||
				menu: [{
 | 
			
		||||
					type: 'item',
 | 
			
		||||
					text: '%i18n:@contextmenu.set-as-avatar%',
 | 
			
		||||
					text: this.$t('contextmenu.set-as-avatar'),
 | 
			
		||||
					action: this.setAsAvatar
 | 
			
		||||
				}, {
 | 
			
		||||
					type: 'item',
 | 
			
		||||
					text: '%i18n:@contextmenu.set-as-banner%',
 | 
			
		||||
					text: this.$t('contextmenu.set-as-banner'),
 | 
			
		||||
					action: this.setAsBanner
 | 
			
		||||
				}]
 | 
			
		||||
			}, /*{
 | 
			
		||||
				type: 'nest',
 | 
			
		||||
				text: '%i18n:@contextmenu.open-in-app%',
 | 
			
		||||
				text: this.$t('contextmenu.open-in-app'),
 | 
			
		||||
				menu: [{
 | 
			
		||||
					type: 'item',
 | 
			
		||||
					text: '%i18n:@contextmenu.add-app%...',
 | 
			
		||||
@@ -148,8 +150,8 @@ export default Vue.extend({
 | 
			
		||||
 | 
			
		||||
		rename() {
 | 
			
		||||
			(this as any).apis.input({
 | 
			
		||||
				title: '%i18n:@contextmenu.rename-file%',
 | 
			
		||||
				placeholder: '%i18n:@contextmenu.input-new-file-name%',
 | 
			
		||||
				title: this.$t('contextmenu.rename-file'),
 | 
			
		||||
				placeholder: this.$t('contextmenu.input-new-file-name'),
 | 
			
		||||
				default: this.file.name,
 | 
			
		||||
				allowEmpty: false
 | 
			
		||||
			}).then(name => {
 | 
			
		||||
@@ -170,10 +172,10 @@ export default Vue.extend({
 | 
			
		||||
		copyUrl() {
 | 
			
		||||
			copyToClipboard(this.file.url);
 | 
			
		||||
			(this as any).apis.dialog({
 | 
			
		||||
				title: '<fa icon="check"/>%i18n:@contextmenu.copied%',
 | 
			
		||||
				text: '%i18n:@contextmenu.copied-url-to-clipboard%',
 | 
			
		||||
				title: this.$t('contextmenu.copied'),
 | 
			
		||||
				text: this.$t('contextmenu.copied-url-to-clipboard'),
 | 
			
		||||
				actions: [{
 | 
			
		||||
					text: '%i18n:common.ok%'
 | 
			
		||||
					text: this.$t('@.ok')
 | 
			
		||||
				}]
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 
 | 
			
		||||
@@ -25,9 +25,11 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import contextmenu from '../../api/contextmenu';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/drive.folder.vue'),
 | 
			
		||||
	props: ['folder'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
@@ -54,22 +56,22 @@ export default Vue.extend({
 | 
			
		||||
			this.isContextmenuShowing = true;
 | 
			
		||||
			contextmenu((this as any).os)(e, [{
 | 
			
		||||
				type: 'item',
 | 
			
		||||
				text: '%i18n:@contextmenu.move-to-this-folder%',
 | 
			
		||||
				text: this.$t('contextmenu.move-to-this-folder'),
 | 
			
		||||
				icon: 'arrow-right',
 | 
			
		||||
				action: this.go
 | 
			
		||||
			}, {
 | 
			
		||||
				type: 'item',
 | 
			
		||||
				text: '%i18n:@contextmenu.show-in-new-window%',
 | 
			
		||||
				text: this.$t('contextmenu.show-in-new-window'),
 | 
			
		||||
				icon: ['far', 'window-restore'],
 | 
			
		||||
				action: this.newWindow
 | 
			
		||||
			}, null, {
 | 
			
		||||
				type: 'item',
 | 
			
		||||
				text: '%i18n:@contextmenu.rename%',
 | 
			
		||||
				text: this.$t('contextmenu.rename'),
 | 
			
		||||
				icon: 'i-cursor',
 | 
			
		||||
				action: this.rename
 | 
			
		||||
			}, null, {
 | 
			
		||||
				type: 'item',
 | 
			
		||||
				text: '%i18n:common.delete%',
 | 
			
		||||
				text: this.$t('@.delete'),
 | 
			
		||||
				icon: ['far', 'trash-alt'],
 | 
			
		||||
				action: this.deleteFolder
 | 
			
		||||
			}], {
 | 
			
		||||
@@ -155,15 +157,15 @@ export default Vue.extend({
 | 
			
		||||
					switch (err) {
 | 
			
		||||
						case 'detected-circular-definition':
 | 
			
		||||
							(this as any).apis.dialog({
 | 
			
		||||
								title: '<fa icon="exclamation-triangle"/>%i18n:@unable-to-process%',
 | 
			
		||||
								text: '%i18n:@circular-reference-detected%',
 | 
			
		||||
								title: this.$t('unable-to-process'),
 | 
			
		||||
								text: this.$t('circular-reference-detected'),
 | 
			
		||||
								actions: [{
 | 
			
		||||
									text: '%i18n:common.ok%'
 | 
			
		||||
									text: this.$t('@.ok')
 | 
			
		||||
								}]
 | 
			
		||||
							});
 | 
			
		||||
							break;
 | 
			
		||||
						default:
 | 
			
		||||
							alert(`%i18n:@unhandled-error% ${err}`);
 | 
			
		||||
							alert(this.$t('unhandled-error'));
 | 
			
		||||
					}
 | 
			
		||||
				});
 | 
			
		||||
			}
 | 
			
		||||
@@ -195,8 +197,8 @@ export default Vue.extend({
 | 
			
		||||
 | 
			
		||||
		rename() {
 | 
			
		||||
			(this as any).apis.input({
 | 
			
		||||
				title: '%i18n:@contextmenu.rename-folder%',
 | 
			
		||||
				placeholder: '%i18n:@contextmenu.input-new-folder-name%',
 | 
			
		||||
				title: this.$t('contextmenu.rename-folder'),
 | 
			
		||||
				placeholder: this.$t('contextmenu.input-new-folder-name'),
 | 
			
		||||
				default: this.folder.name
 | 
			
		||||
			}).then(name => {
 | 
			
		||||
				(this as any).api('drive/folders/update', {
 | 
			
		||||
 
 | 
			
		||||
@@ -8,13 +8,15 @@
 | 
			
		||||
	@drop.stop="onDrop"
 | 
			
		||||
>
 | 
			
		||||
	<i v-if="folder == null" class="cloud"><fa icon="cloud"/></i>
 | 
			
		||||
	<span>{{ folder == null ? '%i18n:common.drive%' : folder.name }}</span>
 | 
			
		||||
	<span>{{ folder == null ? $t('@.drive') : folder.name }}</span>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n(),
 | 
			
		||||
	props: ['folder'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
 
 | 
			
		||||
@@ -30,18 +30,18 @@
 | 
			
		||||
				<x-folder v-for="folder in folders" :key="folder.id" class="folder" :folder="folder"/>
 | 
			
		||||
				<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
 | 
			
		||||
				<div class="padding" v-for="n in 16"></div>
 | 
			
		||||
				<button v-if="moreFolders">%i18n:@load-more%</button>
 | 
			
		||||
				<button v-if="moreFolders">{{ $t('@.load-more') }}</button>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="files" ref="filesContainer" v-if="files.length > 0">
 | 
			
		||||
				<x-file v-for="file in files" :key="file.id" class="file" :file="file"/>
 | 
			
		||||
				<!-- SEE: https://stackoverflow.com/questions/18744164/flex-box-align-last-row-to-grid -->
 | 
			
		||||
				<div class="padding" v-for="n in 16"></div>
 | 
			
		||||
				<button v-if="moreFiles" @click="fetchMoreFiles">%i18n:@load-more%</button>
 | 
			
		||||
				<button v-if="moreFiles" @click="fetchMoreFiles">{{ $t('@.load-more') }}</button>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="empty" v-if="files.length == 0 && folders.length == 0 && !fetching">
 | 
			
		||||
				<p v-if="draghover">%i18n:@empty-draghover%</p>
 | 
			
		||||
				<p v-if="!draghover && folder == null"><strong>%i18n:@empty-drive%</strong><br/>%i18n:@empty-drive-description%</p>
 | 
			
		||||
				<p v-if="!draghover && folder != null">%i18n:@empty-folder%</p>
 | 
			
		||||
				<p v-if="draghover">{{ $t('empty-draghover') }}</p>
 | 
			
		||||
				<p v-if="!draghover && folder == null"><strong>{{ $t('empty-drive') }}</strong><br/>{{ $t('empty-drive-description') }}</p>
 | 
			
		||||
				<p v-if="!draghover && folder != null">{{ $t('empty-folder') }}</p>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="fetching" v-if="fetching">
 | 
			
		||||
@@ -59,6 +59,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import MkDriveWindow from './drive-window.vue';
 | 
			
		||||
import XNavFolder from './drive.nav-folder.vue';
 | 
			
		||||
import XFolder from './drive.folder.vue';
 | 
			
		||||
@@ -68,6 +69,7 @@ import contextmenu from '../../api/contextmenu';
 | 
			
		||||
import { url } from '../../../config';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/drive.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		XNavFolder,
 | 
			
		||||
		XFolder,
 | 
			
		||||
@@ -137,17 +139,17 @@ export default Vue.extend({
 | 
			
		||||
		onContextmenu(e) {
 | 
			
		||||
			contextmenu((this as any).os)(e, [{
 | 
			
		||||
				type: 'item',
 | 
			
		||||
				text: '%i18n:@contextmenu.create-folder%',
 | 
			
		||||
				text: this.$t('contextmenu.create-folder'),
 | 
			
		||||
				icon: ['far', 'folder'],
 | 
			
		||||
				action: this.createFolder
 | 
			
		||||
			}, {
 | 
			
		||||
				type: 'item',
 | 
			
		||||
				text: '%i18n:@contextmenu.upload%',
 | 
			
		||||
				text: this.$t('contextmenu.upload'),
 | 
			
		||||
				icon: 'upload',
 | 
			
		||||
				action: this.selectLocalFile
 | 
			
		||||
			}, {
 | 
			
		||||
				type: 'item',
 | 
			
		||||
				text: '%i18n:@contextmenu.url-upload%',
 | 
			
		||||
				text: this.$t('contextmenu.url-upload'),
 | 
			
		||||
				icon: 'cloud-upload-alt',
 | 
			
		||||
				action: this.urlUpload
 | 
			
		||||
			}]);
 | 
			
		||||
@@ -313,10 +315,10 @@ export default Vue.extend({
 | 
			
		||||
					switch (err) {
 | 
			
		||||
						case 'detected-circular-definition':
 | 
			
		||||
							(this as any).apis.dialog({
 | 
			
		||||
								title: '<fa icon="exclamation-triangle"/>%i18n:@unable-to-process%',
 | 
			
		||||
								text: '%i18n:@circular-reference-detected%',
 | 
			
		||||
								title: this.$t('unable-to-process'),
 | 
			
		||||
								text: this.$t('circular-reference-detected'),
 | 
			
		||||
								actions: [{
 | 
			
		||||
									text: '%i18n:common.ok%'
 | 
			
		||||
									text: this.$t('@.ok')
 | 
			
		||||
								}]
 | 
			
		||||
							});
 | 
			
		||||
							break;
 | 
			
		||||
@@ -334,8 +336,8 @@ export default Vue.extend({
 | 
			
		||||
 | 
			
		||||
		urlUpload() {
 | 
			
		||||
			(this as any).apis.input({
 | 
			
		||||
				title: '%i18n:@url-upload%',
 | 
			
		||||
				placeholder: '%i18n:@url-of-file%'
 | 
			
		||||
				title: this.$t('url-upload'),
 | 
			
		||||
				placeholder: this.$t('url-of-file')
 | 
			
		||||
			}).then(url => {
 | 
			
		||||
				(this as any).api('drive/files/upload_from_url', {
 | 
			
		||||
					url: url,
 | 
			
		||||
@@ -343,10 +345,10 @@ export default Vue.extend({
 | 
			
		||||
				});
 | 
			
		||||
 | 
			
		||||
				(this as any).apis.dialog({
 | 
			
		||||
					title: '<fa icon="check"/>%i18n:@url-upload-requested%',
 | 
			
		||||
					text: '%i18n:@may-take-time%',
 | 
			
		||||
					title: this.$t('url-upload-requested'),
 | 
			
		||||
					text: this.$t('may-take-time'),
 | 
			
		||||
					actions: [{
 | 
			
		||||
						text: '%i18n:common.ok%'
 | 
			
		||||
						text: this.$t('@.ok')
 | 
			
		||||
					}]
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
@@ -354,8 +356,8 @@ export default Vue.extend({
 | 
			
		||||
 | 
			
		||||
		createFolder() {
 | 
			
		||||
			(this as any).apis.input({
 | 
			
		||||
				title: '%i18n:@create-folder%',
 | 
			
		||||
				placeholder: '%i18n:@folder-name%'
 | 
			
		||||
				title: this.$t('create-folder'),
 | 
			
		||||
				placeholder: this.$t('folder-name')
 | 
			
		||||
			}).then(name => {
 | 
			
		||||
				(this as any).api('drive/folders/create', {
 | 
			
		||||
					name: name,
 | 
			
		||||
 
 | 
			
		||||
@@ -5,11 +5,11 @@
 | 
			
		||||
	:disabled="wait"
 | 
			
		||||
>
 | 
			
		||||
	<template v-if="!wait">
 | 
			
		||||
		<template v-if="u.hasPendingFollowRequestFromYou && u.isLocked"><fa icon="hourglass-half"/><template v-if="size == 'big'"> %i18n:@request-pending%</template></template>
 | 
			
		||||
		<template v-else-if="u.hasPendingFollowRequestFromYou && !u.isLocked"><fa icon="hourglass-start"/><template v-if="size == 'big'"> %i18n:@follow-processing%</template></template>
 | 
			
		||||
		<template v-else-if="u.isFollowing"><fa icon="minus"/><template v-if="size == 'big'"> %i18n:@following%</template></template>
 | 
			
		||||
		<template v-else-if="!u.isFollowing && u.isLocked"><fa icon="plus"/><template v-if="size == 'big'"> %i18n:@follow-request%</template></template>
 | 
			
		||||
		<template v-else-if="!u.isFollowing && !u.isLocked"><fa icon="plus"/><template v-if="size == 'big'"> %i18n:@follow%</template></template>
 | 
			
		||||
		<template v-if="u.hasPendingFollowRequestFromYou && u.isLocked"><fa icon="hourglass-half"/><template v-if="size == 'big'"> {{ $t('request-pending') }}</template></template>
 | 
			
		||||
		<template v-else-if="u.hasPendingFollowRequestFromYou && !u.isLocked"><fa icon="hourglass-start"/><template v-if="size == 'big'"> {{ $t('follow-processing') }}</template></template>
 | 
			
		||||
		<template v-else-if="u.isFollowing"><fa icon="minus"/><template v-if="size == 'big'"> {{ $t('following') }}</template></template>
 | 
			
		||||
		<template v-else-if="!u.isFollowing && u.isLocked"><fa icon="plus"/><template v-if="size == 'big'"> {{ $t('follow-request') }}</template></template>
 | 
			
		||||
		<template v-else-if="!u.isFollowing && !u.isLocked"><fa icon="plus"/><template v-if="size == 'big'"> {{ $t('follow') }}</template></template>
 | 
			
		||||
	</template>
 | 
			
		||||
	<template v-else><fa icon="spinner .pulse" fixed-width/></template>
 | 
			
		||||
</button>
 | 
			
		||||
@@ -17,8 +17,10 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/follow-button.vue'),
 | 
			
		||||
	props: {
 | 
			
		||||
		user: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-friends-maker">
 | 
			
		||||
	<p class="title">%i18n:@title%</p>
 | 
			
		||||
	<p class="title">{{ $t('title') }}</p>
 | 
			
		||||
	<div class="users" v-if="!fetching && users.length > 0">
 | 
			
		||||
		<div class="user" v-for="user in users" :key="user.id">
 | 
			
		||||
			<mk-avatar class="avatar" :user="user" target="_blank"/>
 | 
			
		||||
@@ -10,17 +10,19 @@
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
	<p class="empty" v-if="!fetching && users.length == 0">%i18n:@empty%</p>
 | 
			
		||||
	<p class="fetching" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>%i18n:@fetching%<mk-ellipsis/></p>
 | 
			
		||||
	<a class="refresh" @click="refresh">%i18n:@refresh%</a>
 | 
			
		||||
	<button class="close" @click="destroyDom()" title="%i18n:@close%"><fa icon="times"/></button>
 | 
			
		||||
	<p class="empty" v-if="!fetching && users.length == 0">{{ $t('empty') }}</p>
 | 
			
		||||
	<p class="fetching" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>{{ $t('fetching') }}<mk-ellipsis/></p>
 | 
			
		||||
	<a class="refresh" @click="refresh">{{ $t('refresh') }}</a>
 | 
			
		||||
	<button class="close" @click="destroyDom()" :title="$t('title')"><fa icon="times"/></button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/friends-maker.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			users: [],
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,17 @@
 | 
			
		||||
<template>
 | 
			
		||||
<mk-window ref="window" width="500px" height="560px" :popout-url="popout" @closed="destroyDom">
 | 
			
		||||
	<span slot="header" :class="$style.header"><fa icon="gamepad"/>%i18n:@game%</span>
 | 
			
		||||
	<span slot="header" :class="$style.header"><fa icon="gamepad"/>{{ $t('game') }}</span>
 | 
			
		||||
	<x-reversi :class="$style.content" @gamed="g => game = g"/>
 | 
			
		||||
</mk-window>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import { url } from '../../../config';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/game-window.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		XReversi: () => import('../../../common/views/components/games/reversi/reversi.vue')
 | 
			
		||||
	},
 | 
			
		||||
 
 | 
			
		||||
@@ -1,40 +1,40 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-home" :data-customize="customize">
 | 
			
		||||
	<div class="customize" v-if="customize">
 | 
			
		||||
		<router-link to="/"><fa icon="check"/>%i18n:@done%</router-link>
 | 
			
		||||
		<router-link to="/"><fa icon="check"/>{{ $t('done') }}</router-link>
 | 
			
		||||
		<div>
 | 
			
		||||
			<div class="adder">
 | 
			
		||||
				<p>%i18n:@add-widget%</p>
 | 
			
		||||
				<p>{{ $t('add-widget') }}</p>
 | 
			
		||||
				<select v-model="widgetAdderSelected">
 | 
			
		||||
					<option value="profile">%i18n:common.widgets.profile%</option>
 | 
			
		||||
					<option value="analog-clock">%i18n:common.widgets.analog-clock%</option>
 | 
			
		||||
					<option value="calendar">%i18n:common.widgets.calendar%</option>
 | 
			
		||||
					<option value="timemachine">%i18n:common.widgets.timemachine%</option>
 | 
			
		||||
					<option value="activity">%i18n:common.widgets.activity%</option>
 | 
			
		||||
					<option value="rss">%i18n:common.widgets.rss%</option>
 | 
			
		||||
					<option value="trends">%i18n:common.widgets.trends%</option>
 | 
			
		||||
					<option value="photo-stream">%i18n:common.widgets.photo-stream%</option>
 | 
			
		||||
					<option value="slideshow">%i18n:common.widgets.slideshow%</option>
 | 
			
		||||
					<option value="version">%i18n:common.widgets.version%</option>
 | 
			
		||||
					<option value="broadcast">%i18n:common.widgets.broadcast%</option>
 | 
			
		||||
					<option value="notifications">%i18n:common.widgets.notifications%</option>
 | 
			
		||||
					<option value="users">%i18n:common.widgets.users%</option>
 | 
			
		||||
					<option value="polls">%i18n:common.widgets.polls%</option>
 | 
			
		||||
					<option value="post-form">%i18n:common.widgets.post-form%</option>
 | 
			
		||||
					<option value="messaging">%i18n:common.widgets.messaging%</option>
 | 
			
		||||
					<option value="memo">%i18n:common.widgets.memo%</option>
 | 
			
		||||
					<option value="hashtags">%i18n:common.widgets.hashtags%</option>
 | 
			
		||||
					<option value="posts-monitor">%i18n:common.widgets.posts-monitor%</option>
 | 
			
		||||
					<option value="server">%i18n:common.widgets.server%</option>
 | 
			
		||||
					<option value="donation">%i18n:common.widgets.donation%</option>
 | 
			
		||||
					<option value="nav">%i18n:common.widgets.nav%</option>
 | 
			
		||||
					<option value="tips">%i18n:common.widgets.tips%</option>
 | 
			
		||||
					<option value="profile">{{ $t('@.widgets.profile') }}</option>
 | 
			
		||||
					<option value="analog-clock">{{ $t('@.widgets.analog-clock') }}</option>
 | 
			
		||||
					<option value="calendar">{{ $t('@.widgets.calendar') }}</option>
 | 
			
		||||
					<option value="timemachine">{{ $t('@.widgets.timemachine') }}</option>
 | 
			
		||||
					<option value="activity">{{ $t('@.widgets.activity') }}</option>
 | 
			
		||||
					<option value="rss">{{ $t('@.widgets.rss') }}</option>
 | 
			
		||||
					<option value="trends">{{ $t('@.widgets.trends') }}</option>
 | 
			
		||||
					<option value="photo-stream">{{ $t('@.widgets.photo-stream') }}</option>
 | 
			
		||||
					<option value="slideshow">{{ $t('@.widgets.slideshow') }}</option>
 | 
			
		||||
					<option value="version">{{ $t('@.widgets.version') }}</option>
 | 
			
		||||
					<option value="broadcast">{{ $t('@.widgets.broadcast') }}</option>
 | 
			
		||||
					<option value="notifications">{{ $t('@.widgets.notifications') }}</option>
 | 
			
		||||
					<option value="users">{{ $t('@.widgets.users') }}</option>
 | 
			
		||||
					<option value="polls">{{ $t('@.widgets.polls') }}</option>
 | 
			
		||||
					<option value="post-form">{{ $t('@.widgets.post-form') }}</option>
 | 
			
		||||
					<option value="messaging">{{ $t('@.widgets.messaging') }}</option>
 | 
			
		||||
					<option value="memo">{{ $t('@.widgets.memo') }}</option>
 | 
			
		||||
					<option value="hashtags">{{ $t('@.widgets.hashtags') }}</option>
 | 
			
		||||
					<option value="posts-monitor">{{ $t('@.widgets.posts-monitor') }}</option>
 | 
			
		||||
					<option value="server">{{ $t('@.widgets.server') }}</option>
 | 
			
		||||
					<option value="donation">{{ $t('@.widgets.donation') }}</option>
 | 
			
		||||
					<option value="nav">{{ $t('@.widgets.nav') }}</option>
 | 
			
		||||
					<option value="tips">{{ $t('@.widgets.tips') }}</option>
 | 
			
		||||
				</select>
 | 
			
		||||
				<button @click="addWidget">%i18n:@add%</button>
 | 
			
		||||
				<button @click="addWidget">{{ $t('add') }}</button>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div class="trash">
 | 
			
		||||
				<x-draggable v-model="trash" :options="{ group: 'x' }" @add="onTrash"></x-draggable>
 | 
			
		||||
				<p>%i18n:common.trash%</p>
 | 
			
		||||
				<p>{{ $t('@.trash') }}</p>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
@@ -53,7 +53,7 @@
 | 
			
		||||
				</div>
 | 
			
		||||
			</x-draggable>
 | 
			
		||||
			<div class="main">
 | 
			
		||||
				<a @click="hint">%i18n:common.customization-tips.title%</a>
 | 
			
		||||
				<a @click="hint">{{ $t('@.customization-tips.title') }}</a>
 | 
			
		||||
				<div>
 | 
			
		||||
					<mk-post-form v-if="$store.state.settings.showPostFormOnTopOfTl"/>
 | 
			
		||||
					<mk-timeline ref="tl" @loaded="onTlLoaded"/>
 | 
			
		||||
@@ -75,6 +75,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import * as XDraggable from 'vuedraggable';
 | 
			
		||||
import * as uuid from 'uuid';
 | 
			
		||||
 | 
			
		||||
@@ -123,6 +124,7 @@ defaultDesktopHomeWidgets.right.forEach(widget => {
 | 
			
		||||
//#endregion
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/home.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		XDraggable
 | 
			
		||||
	},
 | 
			
		||||
@@ -185,13 +187,10 @@ export default Vue.extend({
 | 
			
		||||
	methods: {
 | 
			
		||||
		hint() {
 | 
			
		||||
			(this as any).apis.dialog({
 | 
			
		||||
				title: '<fa icon="info-circle"/>%i18n:common.customization-tips.title%',
 | 
			
		||||
				text: '<p>%i18n:common.customization-tips.paragraph1%</p>' +
 | 
			
		||||
					'<p>%i18n:common.customization-tips.paragraph2%</p>' +
 | 
			
		||||
					'<p>%i18n:common.customization-tips.paragraph3%</p>' +
 | 
			
		||||
					'<p>%i18n:common.customization-tips.paragraph4%</p>',
 | 
			
		||||
				title: this.$t('@.customization-tips.title'),
 | 
			
		||||
				text: this.$t('@.customization-tips.paragraph'),
 | 
			
		||||
				actions: [{
 | 
			
		||||
					text: '%i18n:common.customization-tips.gotit%'
 | 
			
		||||
					text: this.$t('@.customization-tips.gotit')
 | 
			
		||||
				}]
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
 
 | 
			
		||||
@@ -8,15 +8,17 @@
 | 
			
		||||
		<input ref="text" v-model="text" :type="type" @keydown="onKeydown" :placeholder="placeholder"/>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div :class="$style.actions">
 | 
			
		||||
		<button :class="$style.cancel" @click="cancel">%i18n:@cancel%</button>
 | 
			
		||||
		<button :class="$style.ok" :disabled="!allowEmpty && text.length == 0" @click="ok">%i18n:@ok%</button>
 | 
			
		||||
		<button :class="$style.cancel" @click="cancel">{{ $t('cancel') }}</button>
 | 
			
		||||
		<button :class="$style.ok" :disabled="!allowEmpty && text.length == 0" @click="ok">{{ $t('ok') }}</button>
 | 
			
		||||
	</div>
 | 
			
		||||
</mk-window>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/input-dialog.vue'),
 | 
			
		||||
	props: {
 | 
			
		||||
		title: {
 | 
			
		||||
			type: String
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="ldwbgwstjsdgcjruamauqdrffetqudry" v-if="image.isSensitive && hide && !$store.state.device.alwaysShowNsfw" @click="hide = false">
 | 
			
		||||
	<div>
 | 
			
		||||
		<b><fa icon="exclamation-triangle"/> %i18n:@sensitive%</b>
 | 
			
		||||
		<span>%i18n:@click-to-show%</span>
 | 
			
		||||
		<b><fa icon="exclamation-triangle"/> {{ $t('sensitive') }}</b>
 | 
			
		||||
		<span>{{ $t('click-to-show') }}</span>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
<a class="lcjomzwbohoelkxsnuqjiaccdbdfiazy" v-else
 | 
			
		||||
@@ -17,9 +17,11 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import ImageViewer from '../../../common/views/components/image-viewer.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/media-image.vue'),
 | 
			
		||||
	props: {
 | 
			
		||||
		image: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="uofhebxjdgksfmltszlxurtjnjjsvioh" v-if="video.isSensitive && hide" @click="hide = false">
 | 
			
		||||
	<div>
 | 
			
		||||
		<b><fa icon="exclamation-triangle"/> %i18n:@sensitive%</b>
 | 
			
		||||
		<span>%i18n:@click-to-show%</span>
 | 
			
		||||
		<b><fa icon="exclamation-triangle"/> {{ $t('sensitive') }}</b>
 | 
			
		||||
		<span>{{ $t('click-to-show') }}</span>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
<div class="vwxdhznewyashiknzolsoihtlpicqepe" v-else>
 | 
			
		||||
@@ -19,9 +19,11 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import MkMediaVideoDialog from './media-video-dialog.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/media-video.vue'),
 | 
			
		||||
	props: {
 | 
			
		||||
		video: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,18 @@
 | 
			
		||||
<template>
 | 
			
		||||
<mk-window ref="window" width="500px" height="560px" :popout-url="popout" @closed="destroyDom">
 | 
			
		||||
	<span slot="header" :class="$style.header"><fa icon="comments"/>%i18n:@title% {{ user | userName }}</span>
 | 
			
		||||
	<span slot="header" :class="$style.header"><fa icon="comments"/>{{ $t('title') }} {{ user | userName }}</span>
 | 
			
		||||
	<mk-messaging-room :user="user" :class="$style.content"/>
 | 
			
		||||
</mk-window>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import { url } from '../../../config';
 | 
			
		||||
import getAcct from '../../../../../misc/acct/render';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/messaging-room-window.vue'),
 | 
			
		||||
	props: ['user'],
 | 
			
		||||
	computed: {
 | 
			
		||||
		popout(): string {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,17 @@
 | 
			
		||||
<template>
 | 
			
		||||
<mk-window ref="window" width="500px" height="560px" @closed="destroyDom">
 | 
			
		||||
	<span slot="header" :class="$style.header"><fa icon="comments"/>%i18n:@title%</span>
 | 
			
		||||
	<span slot="header" :class="$style.header"><fa icon="comments"/>{{ $t('title') }}</span>
 | 
			
		||||
	<mk-messaging :class="$style.content" @navigate="navigate"/>
 | 
			
		||||
</mk-window>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import MkMessagingRoomWindow from './messaging-room-window.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/messaging-window.vue'),
 | 
			
		||||
	methods: {
 | 
			
		||||
		navigate(user) {
 | 
			
		||||
			(this as any).os.new(MkMessagingRoomWindow, {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,7 +3,7 @@
 | 
			
		||||
	<button
 | 
			
		||||
		class="read-more"
 | 
			
		||||
		v-if="p.reply && p.reply.replyId && conversation.length == 0"
 | 
			
		||||
		title="%i18n:@more%"
 | 
			
		||||
		:title="$t('title')"
 | 
			
		||||
		@click="fetchConversation"
 | 
			
		||||
		:disabled="conversationFetching"
 | 
			
		||||
	>
 | 
			
		||||
@@ -21,9 +21,9 @@
 | 
			
		||||
			<mk-avatar class="avatar" :user="note.user"/>
 | 
			
		||||
			<fa icon="retweet"/>
 | 
			
		||||
			<router-link class="name" :href="note.user | userPage">{{ note.user | userName }}</router-link>
 | 
			
		||||
			<span>{{ '%i18n:@reposted-by%'.substr(0, '%i18n:@reposted-by%'.indexOf('{')) }}</span>
 | 
			
		||||
			<span>{{ this.$t('reposted-by').substr(0, this.$t('reposted-by').indexOf('{')) }}</span>
 | 
			
		||||
			<a class="name" :href="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</a>
 | 
			
		||||
			<span>{{ '%i18n:@reposted-by%'.substr('%i18n:@reposted-by%'.indexOf('}') + 1) }}</span>
 | 
			
		||||
			<span>{{ this.$t('reposted-by').substr(this.$t('reposted-by').indexOf('}') + 1) }}</span>
 | 
			
		||||
			<mk-time :time="note.createdAt"/>
 | 
			
		||||
		</p>
 | 
			
		||||
	</div>
 | 
			
		||||
@@ -43,8 +43,8 @@
 | 
			
		||||
			</p>
 | 
			
		||||
			<div class="content" v-show="p.cw == null || showContent">
 | 
			
		||||
				<div class="text">
 | 
			
		||||
					<span v-if="p.isHidden" style="opacity: 0.5">%i18n:@private%</span>
 | 
			
		||||
					<span v-if="p.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span>
 | 
			
		||||
					<span v-if="p.isHidden" style="opacity: 0.5">{{ $t('private') }}</span>
 | 
			
		||||
					<span v-if="p.deletedAt" style="opacity: 0.5">{{ $t('deleted') }}</span>
 | 
			
		||||
					<misskey-flavored-markdown v-if="p.text" :text="p.text" :i="$store.state.i" :customEmojis="p.emojis" />
 | 
			
		||||
				</div>
 | 
			
		||||
				<div class="files" v-if="p.files.length > 0">
 | 
			
		||||
@@ -52,7 +52,7 @@
 | 
			
		||||
				</div>
 | 
			
		||||
				<mk-poll v-if="p.poll" :note="p"/>
 | 
			
		||||
				<mk-url-preview v-for="url in urls" :url="url" :key="url" :detail="true"/>
 | 
			
		||||
				<a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank"><fa icon="map-marker-alt"/> %i18n:@location%</a>
 | 
			
		||||
				<a class="location" v-if="p.geo" :href="`https://maps.google.com/maps?q=${p.geo.coordinates[1]},${p.geo.coordinates[0]}`" target="_blank"><fa icon="map-marker-alt"/> {{ $t('location') }}</a>
 | 
			
		||||
				<div class="map" v-if="p.geo" ref="map"></div>
 | 
			
		||||
				<div class="renote" v-if="p.renote">
 | 
			
		||||
					<mk-note-preview :note="p.renote"/>
 | 
			
		||||
@@ -67,10 +67,10 @@
 | 
			
		||||
				<template v-else><fa icon="reply"/></template>
 | 
			
		||||
				<p class="count" v-if="p.repliesCount > 0">{{ p.repliesCount }}</p>
 | 
			
		||||
			</button>
 | 
			
		||||
			<button class="renoteButton" @click="renote" title="%i18n:@renote%">
 | 
			
		||||
			<button class="renoteButton" @click="renote" :title="$t('title')">
 | 
			
		||||
				<fa icon="retweet"/><p class="count" v-if="p.renoteCount > 0">{{ p.renoteCount }}</p>
 | 
			
		||||
			</button>
 | 
			
		||||
			<button class="reactionButton" :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" title="%i18n:@add-reaction%">
 | 
			
		||||
			<button class="reactionButton" :class="{ reacted: p.myReaction != null }" @click="react" ref="reactButton" :title="$t('title')">
 | 
			
		||||
				<fa icon="plus"/><p class="count" v-if="p.reactions_count > 0">{{ p.reactions_count }}</p>
 | 
			
		||||
			</button>
 | 
			
		||||
			<button @click="menu" ref="menuButton">
 | 
			
		||||
@@ -86,6 +86,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import parse from '../../../../../mfm/parse';
 | 
			
		||||
 | 
			
		||||
import MkPostFormWindow from './post-form-window.vue';
 | 
			
		||||
@@ -97,6 +98,7 @@ import { sum } from '../../../../../prelude/array';
 | 
			
		||||
import noteSubscriber from '../../../common/scripts/note-subscriber';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/note-detail.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		XSub
 | 
			
		||||
	},
 | 
			
		||||
 
 | 
			
		||||
@@ -16,9 +16,9 @@
 | 
			
		||||
	<div class="renote" v-if="isRenote">
 | 
			
		||||
		<mk-avatar class="avatar" :user="note.user"/>
 | 
			
		||||
		<fa icon="retweet"/>
 | 
			
		||||
		<span>{{ '%i18n:@reposted-by%'.substr(0, '%i18n:@reposted-by%'.indexOf('{')) }}</span>
 | 
			
		||||
		<span>{{ this.$t('reposted-by').substr(0, this.$t('reposted-by').indexOf('{')) }}</span>
 | 
			
		||||
		<router-link class="name" :to="note.user | userPage" v-user-preview="note.userId">{{ note.user | userName }}</router-link>
 | 
			
		||||
		<span>{{ '%i18n:@reposted-by%'.substr('%i18n:@reposted-by%'.indexOf('}') + 1) }}</span>
 | 
			
		||||
		<span>{{ this.$t('reposted-by').substr(this.$t('reposted-by').indexOf('}') + 1) }}</span>
 | 
			
		||||
		<mk-time :time="note.createdAt"/>
 | 
			
		||||
	</div>
 | 
			
		||||
	<article>
 | 
			
		||||
@@ -32,7 +32,7 @@
 | 
			
		||||
				</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>
 | 
			
		||||
						<span v-if="appearNote.isHidden" style="opacity: 0.5">{{ $t('private') }}</span>
 | 
			
		||||
						<a class="reply" v-if="appearNote.reply"><fa icon="reply"/></a>
 | 
			
		||||
						<misskey-flavored-markdown v-if="appearNote.text" :text="appearNote.text" :i="$store.state.i" :class="$style.text" :customEmojis="appearNote.emojis"/>
 | 
			
		||||
						<a class="rp" v-if="appearNote.renote">RN:</a>
 | 
			
		||||
@@ -49,15 +49,15 @@
 | 
			
		||||
			<footer>
 | 
			
		||||
				<span class="app" v-if="appearNote.app && mini">via <b>{{ appearNote.app.name }}</b></span>
 | 
			
		||||
				<mk-reactions-viewer :note="appearNote" ref="reactionsViewer"/>
 | 
			
		||||
				<button class="replyButton" @click="reply()" title="%i18n:@reply%">
 | 
			
		||||
				<button class="replyButton" @click="reply()" :title="$t('reply')">
 | 
			
		||||
					<template v-if="appearNote.reply"><fa icon="reply-all"/></template>
 | 
			
		||||
					<template v-else><fa icon="reply"/></template>
 | 
			
		||||
					<p class="count" v-if="appearNote.repliesCount > 0">{{ appearNote.repliesCount }}</p>
 | 
			
		||||
				</button>
 | 
			
		||||
				<button class="renoteButton" @click="renote()" title="%i18n:@renote%">
 | 
			
		||||
				<button class="renoteButton" @click="renote()" :title="$t('renote')">
 | 
			
		||||
					<fa icon="retweet"/><p class="count" v-if="appearNote.renoteCount > 0">{{ appearNote.renoteCount }}</p>
 | 
			
		||||
				</button>
 | 
			
		||||
				<button class="reactionButton" :class="{ reacted: appearNote.myReaction != null }" @click="react()" ref="reactButton" title="%i18n:@add-reaction%">
 | 
			
		||||
				<button class="reactionButton" :class="{ reacted: appearNote.myReaction != null }" @click="react()" ref="reactButton" :title="$t('add-reaction')">
 | 
			
		||||
					<fa icon="plus"/><p class="count" v-if="appearNote.reactions_count > 0">{{ appearNote.reactions_count }}</p>
 | 
			
		||||
				</button>
 | 
			
		||||
				<button @click="menu()" ref="menuButton">
 | 
			
		||||
@@ -74,12 +74,14 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
import XSub from './note.sub.vue';
 | 
			
		||||
import noteMixin from '../../../common/scripts/note-mixin';
 | 
			
		||||
import noteSubscriber from '../../../common/scripts/note-subscriber';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/note.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		XSub
 | 
			
		||||
	},
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@
 | 
			
		||||
 | 
			
		||||
	<footer v-if="more">
 | 
			
		||||
		<button @click="loadMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
 | 
			
		||||
			<template v-if="!moreFetching">%i18n:@load-more%</template>
 | 
			
		||||
			<template v-if="!moreFetching">{{ $t('@.load-more') }}</template>
 | 
			
		||||
			<template v-if="moreFetching"><fa icon="spinner .pulse" fixed-width/></template>
 | 
			
		||||
		</button>
 | 
			
		||||
	</footer>
 | 
			
		||||
@@ -34,6 +34,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import * as config from '../../../config';
 | 
			
		||||
 | 
			
		||||
import XNote from './note.vue';
 | 
			
		||||
@@ -41,6 +42,7 @@ import XNote from './note.vue';
 | 
			
		||||
const displayLimit = 30;
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n(),
 | 
			
		||||
	components: {
 | 
			
		||||
		XNote
 | 
			
		||||
	},
 | 
			
		||||
@@ -68,7 +70,7 @@ export default Vue.extend({
 | 
			
		||||
				const date = new Date(note.createdAt).getDate();
 | 
			
		||||
				const month = new Date(note.createdAt).getMonth() + 1;
 | 
			
		||||
				note._date = date;
 | 
			
		||||
				note._datetext = '%i18n:common.month-and-day%'.replace('{month}', month.toString()).replace('{day}', date.toString());
 | 
			
		||||
				note._datetext = this.$t('@.month-and-day').replace('{month}', month.toString()).replace('{day}', date.toString());
 | 
			
		||||
				return note;
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -105,17 +105,19 @@
 | 
			
		||||
		</component>
 | 
			
		||||
	</div>
 | 
			
		||||
	<button class="more" :class="{ fetching: fetchingMoreNotifications }" v-if="moreNotifications" @click="fetchMoreNotifications" :disabled="fetchingMoreNotifications">
 | 
			
		||||
		<template v-if="fetchingMoreNotifications"><fa icon="spinner .pulse" fixed-width/></template>{{ fetchingMoreNotifications ? '%i18n:common.loading%' : '%i18n:@more%' }}
 | 
			
		||||
		<template v-if="fetchingMoreNotifications"><fa icon="spinner .pulse" fixed-width/></template>{{ fetchingMoreNotifications ? $t('@.loading') : $t('@.load-more') }}
 | 
			
		||||
	</button>
 | 
			
		||||
	<p class="empty" v-if="notifications.length == 0 && !fetching">%i18n:@empty%</p>
 | 
			
		||||
	<p class="empty" v-if="notifications.length == 0 && !fetching">{{ $t('empty') }}</p>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import getNoteSummary from '../../../../../misc/get-note-summary';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n(),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
@@ -133,7 +135,7 @@ export default Vue.extend({
 | 
			
		||||
				const date = new Date(notification.createdAt).getDate();
 | 
			
		||||
				const month = new Date(notification.createdAt).getMonth() + 1;
 | 
			
		||||
				notification._date = date;
 | 
			
		||||
				notification._datetext = '%i18n:common.month-and-day%'.replace('{month}', month.toString()).replace('{day}', date.toString());
 | 
			
		||||
				notification._datetext = this.$t('@.month-and-day').replace('{month}', month.toString()).replace('{day}', date.toString());
 | 
			
		||||
				return notification;
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -2,10 +2,10 @@
 | 
			
		||||
<mk-window class="mk-post-form-window" ref="window" is-modal @closed="onWindowClosed" :animation="animation">
 | 
			
		||||
	<span slot="header" class="mk-post-form-window--header">
 | 
			
		||||
		<span class="icon" v-if="geo"><fa icon="map-marker-alt"/></span>
 | 
			
		||||
		<span v-if="!reply">%i18n:@note%</span>
 | 
			
		||||
		<span v-if="reply">%i18n:@reply%</span>
 | 
			
		||||
		<span class="count" v-if="files.length != 0">{{ '%i18n:@attaches%'.replace('{}', files.length) }}</span>
 | 
			
		||||
		<span class="count" v-if="uploadings.length != 0">{{ '%i18n:@uploading-media%'.replace('{}', uploadings.length) }}<mk-ellipsis/></span>
 | 
			
		||||
		<span v-if="!reply">{{ $t('note') }}</span>
 | 
			
		||||
		<span v-if="reply">{{ $t('reply') }}</span>
 | 
			
		||||
		<span class="count" v-if="files.length != 0">{{ this.$t('attaches').replace('{}', files.length) }}</span>
 | 
			
		||||
		<span class="count" v-if="uploadings.length != 0">{{ this.$t('uploading-media').replace('{}', uploadings.length) }}<mk-ellipsis/></span>
 | 
			
		||||
	</span>
 | 
			
		||||
 | 
			
		||||
	<div class="mk-post-form-window--body">
 | 
			
		||||
@@ -23,8 +23,10 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/post-form-window.vue'),
 | 
			
		||||
	props: {
 | 
			
		||||
		reply: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
 
 | 
			
		||||
@@ -8,13 +8,13 @@
 | 
			
		||||
	<div class="content">
 | 
			
		||||
		<div v-if="visibility == 'specified'" class="visibleUsers">
 | 
			
		||||
			<span v-for="u in visibleUsers">{{ u | userName }}<a @click="removeVisibleUser(u)">[x]</a></span>
 | 
			
		||||
			<a @click="addVisibleUser">%i18n:@add-visible-user%</a>
 | 
			
		||||
			<a @click="addVisibleUser">{{ $t('add-visible-user') }}</a>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="hashtags" v-if="recentHashtags.length > 0 && $store.state.settings.suggestRecentHashtags">
 | 
			
		||||
			<b>%i18n:@recent-tags%:</b>
 | 
			
		||||
			<a v-for="tag in recentHashtags.slice(0, 5)" @click="addTag(tag)" title="%i18n:@click-to-tagging%">#{{ tag }}</a>
 | 
			
		||||
			<b>{{ $t('recent-tags') }}:</b>
 | 
			
		||||
			<a v-for="tag in recentHashtags.slice(0, 5)" @click="addTag(tag)" :title="$t('click-to-tagging')">#{{ tag }}</a>
 | 
			
		||||
		</div>
 | 
			
		||||
		<input v-show="useCw" v-model="cw" placeholder="%i18n:@annotations%">
 | 
			
		||||
		<input v-show="useCw" v-model="cw" :placeholder="$t('placeholder')">
 | 
			
		||||
		<textarea :class="{ with: (files.length != 0 || poll) }"
 | 
			
		||||
			ref="text" v-model="text" :disabled="posting"
 | 
			
		||||
			@keydown="onKeydown" @paste="onPaste" :placeholder="placeholder"
 | 
			
		||||
@@ -24,7 +24,7 @@
 | 
			
		||||
			<x-draggable :list="files" :options="{ animation: 150 }">
 | 
			
		||||
				<div v-for="file in files" :key="file.id">
 | 
			
		||||
					<div class="img" :style="{ backgroundImage: `url(${file.thumbnailUrl})` }" :title="file.name"></div>
 | 
			
		||||
					<img class="remove" @click="detachMedia(file.id)" src="/assets/desktop/remove.png" title="%i18n:@attach-cancel%" alt=""/>
 | 
			
		||||
					<img class="remove" @click="detachMedia(file.id)" src="/assets/desktop/remove.png" :title="$t('attach-cancel')" alt=""/>
 | 
			
		||||
				</div>
 | 
			
		||||
			</x-draggable>
 | 
			
		||||
			<p class="remain">{{ 4 - files.length }}/4</p>
 | 
			
		||||
@@ -32,13 +32,13 @@
 | 
			
		||||
		<mk-poll-editor v-if="poll" ref="poll" @destroyed="poll = false" @updated="saveDraft()"/>
 | 
			
		||||
	</div>
 | 
			
		||||
	<mk-uploader ref="uploader" @uploaded="attachMedia" @change="onChangeUploadings"/>
 | 
			
		||||
	<button class="upload" title="%i18n:@attach-media-from-local%" @click="chooseFile"><fa icon="upload"/></button>
 | 
			
		||||
	<button class="drive" title="%i18n:@attach-media-from-drive%" @click="chooseFileFromDrive"><fa icon="cloud"/></button>
 | 
			
		||||
	<button class="kao" title="%i18n:@insert-a-kao%" @click="kao"><fa :icon="['far', 'smile']"/></button>
 | 
			
		||||
	<button class="poll" title="%i18n:@create-poll%" @click="poll = !poll"><fa icon="chart-pie"/></button>
 | 
			
		||||
	<button class="poll" title="%i18n:@hide-contents%" @click="useCw = !useCw"><fa icon="eye-slash"/></button>
 | 
			
		||||
	<button class="geo" title="%i18n:@attach-location-information%" @click="geo ? removeGeo() : setGeo()"><fa icon="map-marker-alt"/></button>
 | 
			
		||||
	<button class="visibility" title="%i18n:@visibility%" @click="setVisibility" ref="visibilityButton">
 | 
			
		||||
	<button class="upload" :title="$t('attach-media-from-local')" @click="chooseFile"><fa icon="upload"/></button>
 | 
			
		||||
	<button class="drive" :title="$t('attach-media-from-drive')" @click="chooseFileFromDrive"><fa icon="cloud"/></button>
 | 
			
		||||
	<button class="kao" :title="$t('insert-a-kao')" @click="kao"><fa :icon="['far', 'smile']"/></button>
 | 
			
		||||
	<button class="poll" :title="$t('create-poll')" @click="poll = !poll"><fa icon="chart-pie"/></button>
 | 
			
		||||
	<button class="cw%" :title="$t('hide-contents%')" @click="useCw = !useCw"><fa icon="eye-slash"/></button>
 | 
			
		||||
	<button class="geo" :title="$t('attach-location-information')" @click="geo ? removeGeo() : setGeo()"><fa icon="map-marker-alt"/></button>
 | 
			
		||||
	<button class="visibility" :title="$t('visibility')" @click="setVisibility" ref="visibilityButton">
 | 
			
		||||
		<span v-if="visibility === 'public'"><fa icon="globe"/></span>
 | 
			
		||||
		<span v-if="visibility === 'home'"><fa icon="home"/></span>
 | 
			
		||||
		<span v-if="visibility === 'followers'"><fa icon="unlock"/></span>
 | 
			
		||||
@@ -47,7 +47,7 @@
 | 
			
		||||
	</button>
 | 
			
		||||
	<p class="text-count" :class="{ over: this.trimmedLength(text) > this.maxNoteTextLength }">{{ this.maxNoteTextLength - this.trimmedLength(text) }}</p>
 | 
			
		||||
	<button :class="{ posting }" class="submit" :disabled="!canPost" @click="post">
 | 
			
		||||
		{{ posting ? '%i18n:@posting%' : submitText }}<mk-ellipsis v-if="posting"/>
 | 
			
		||||
		{{ posting ? this.$t('posting') : submitText }}<mk-ellipsis v-if="posting"/>
 | 
			
		||||
	</button>
 | 
			
		||||
	<input ref="file" type="file" multiple="multiple" tabindex="-1" @change="onChangeFile"/>
 | 
			
		||||
	<div class="dropzone" v-if="draghover"></div>
 | 
			
		||||
@@ -56,6 +56,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import insertTextAtCursor from 'insert-text-at-cursor';
 | 
			
		||||
import * as XDraggable from 'vuedraggable';
 | 
			
		||||
import getFace from '../../../common/scripts/get-face';
 | 
			
		||||
@@ -68,6 +69,7 @@ import parseAcct from '../../../../../misc/acct/parse';
 | 
			
		||||
import { toASCII } from 'punycode';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/post-form.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		XDraggable,
 | 
			
		||||
		MkVisibilityChooser
 | 
			
		||||
@@ -129,28 +131,28 @@ export default Vue.extend({
 | 
			
		||||
 | 
			
		||||
		placeholder(): string {
 | 
			
		||||
			const xs = [
 | 
			
		||||
				'%i18n:common.note-placeholders.a%',
 | 
			
		||||
				'%i18n:common.note-placeholders.b%',
 | 
			
		||||
				'%i18n:common.note-placeholders.c%',
 | 
			
		||||
				'%i18n:common.note-placeholders.d%',
 | 
			
		||||
				'%i18n:common.note-placeholders.e%',
 | 
			
		||||
				'%i18n:common.note-placeholders.f%'
 | 
			
		||||
				this.$t('@.note-placeholders.a'),
 | 
			
		||||
				this.$t('@.note-placeholders.b'),
 | 
			
		||||
				this.$t('@.note-placeholders.c'),
 | 
			
		||||
				this.$t('@.note-placeholders.d'),
 | 
			
		||||
				this.$t('@.note-placeholders.e'),
 | 
			
		||||
				this.$t('@.note-placeholders.f')
 | 
			
		||||
			];
 | 
			
		||||
			const x = xs[Math.floor(Math.random() * xs.length)];
 | 
			
		||||
 | 
			
		||||
			return this.renote
 | 
			
		||||
				? '%i18n:@quote-placeholder%'
 | 
			
		||||
				? this.$t('quote-placeholder')
 | 
			
		||||
				: this.reply
 | 
			
		||||
					? '%i18n:@reply-placeholder%'
 | 
			
		||||
					? this.$t('reply-placeholder')
 | 
			
		||||
					: x;
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		submitText(): string {
 | 
			
		||||
			return this.renote
 | 
			
		||||
				? '%i18n:@renote%'
 | 
			
		||||
				? this.$t('renote')
 | 
			
		||||
				: this.reply
 | 
			
		||||
					? '%i18n:@reply%'
 | 
			
		||||
					: '%i18n:@submit%';
 | 
			
		||||
					? this.$t('reply')
 | 
			
		||||
					: this.$t('submit');
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		canPost(): boolean {
 | 
			
		||||
@@ -332,7 +334,7 @@ export default Vue.extend({
 | 
			
		||||
 | 
			
		||||
		setGeo() {
 | 
			
		||||
			if (navigator.geolocation == null) {
 | 
			
		||||
				alert('%i18n:@geolocation-alert%');
 | 
			
		||||
				alert(this.$t('geolocation-alert'));
 | 
			
		||||
				return;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@@ -362,7 +364,7 @@ export default Vue.extend({
 | 
			
		||||
 | 
			
		||||
		addVisibleUser() {
 | 
			
		||||
			(this as any).apis.input({
 | 
			
		||||
				title: '%i18n:@enter-username%'
 | 
			
		||||
				title: this.$t('enter-username')
 | 
			
		||||
			}).then(acct => {
 | 
			
		||||
				if (acct.startsWith('@')) acct = acct.substr(1);
 | 
			
		||||
				(this as any).api('users/show', parseAcct(acct)).then(user => {
 | 
			
		||||
@@ -400,16 +402,16 @@ export default Vue.extend({
 | 
			
		||||
				this.deleteDraft();
 | 
			
		||||
				this.$emit('posted');
 | 
			
		||||
				(this as any).apis.notify(this.renote
 | 
			
		||||
					? '%i18n:@reposted%'
 | 
			
		||||
					? this.$t('reposted')
 | 
			
		||||
					: this.reply
 | 
			
		||||
						? '%i18n:@replied%'
 | 
			
		||||
						: '%i18n:@posted%');
 | 
			
		||||
						? this.$t('replied')
 | 
			
		||||
						: this.$t('posted'));
 | 
			
		||||
			}).catch(err => {
 | 
			
		||||
				(this as any).apis.notify(this.renote
 | 
			
		||||
					? '%i18n:@renote-failed%'
 | 
			
		||||
					? this.$t('renote-failed')
 | 
			
		||||
					: this.reply
 | 
			
		||||
						? '%i18n:@reply-failed%'
 | 
			
		||||
						: '%i18n:@note-failed%');
 | 
			
		||||
						? this.$t('reply-failed')
 | 
			
		||||
						: this.$t('note-failed'));
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				this.posting = false;
 | 
			
		||||
			});
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
<mk-window ref="window" :is-modal="false" :can-close="false" width="500px" @closed="destroyDom">
 | 
			
		||||
	<span slot="header">{{ title }}<mk-ellipsis/></span>
 | 
			
		||||
	<div :class="$style.body">
 | 
			
		||||
		<p :class="$style.init" v-if="isNaN(value)">%i18n:@waiting%<mk-ellipsis/></p>
 | 
			
		||||
		<p :class="$style.init" v-if="isNaN(value)">{{ $t('waiting') }}<mk-ellipsis/></p>
 | 
			
		||||
		<p :class="$style.percentage" v-if="!isNaN(value)">{{ Math.floor((value / max) * 100) }}</p>
 | 
			
		||||
		<progress :class="$style.progress"
 | 
			
		||||
			v-if="!isNaN(value) && value < max"
 | 
			
		||||
@@ -16,7 +16,10 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/progress-dialog.vue'),
 | 
			
		||||
	props: ['title', 'initValue', 'initMax'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
<template>
 | 
			
		||||
<mk-window ref="window" is-modal width="450px" height="500px" @closed="destroyDom">
 | 
			
		||||
	<span slot="header"><fa :icon="['far', 'envelope']"/> %i18n:@title%</span>
 | 
			
		||||
	<span slot="header"><fa :icon="['far', 'envelope']"/> {{ $t('title') }}</span>
 | 
			
		||||
 | 
			
		||||
	<div class="slpqaxdoxhvglersgjukmvizkqbmbokc">
 | 
			
		||||
		<div v-for="req in requests">
 | 
			
		||||
			<router-link :key="req.id" :to="req.follower | userPage">{{ req.follower | userName }}</router-link>
 | 
			
		||||
			<span>
 | 
			
		||||
				<a @click="accept(req.follower)">%i18n:@accept%</a>|<a @click="reject(req.follower)">%i18n:@reject%</a>
 | 
			
		||||
				<a @click="accept(req.follower)">{{ $t('accept') }}</a>|<a @click="reject(req.follower)">{{ $t('reject') }}</a>
 | 
			
		||||
			</span>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
@@ -15,7 +15,10 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/received-follow-requests-window.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,14 +1,16 @@
 | 
			
		||||
<template>
 | 
			
		||||
<mk-window ref="window" is-modal @closed="onWindowClosed" :animation="animation">
 | 
			
		||||
	<span slot="header" :class="$style.header"><fa icon="retweet"/>%i18n:@title%</span>
 | 
			
		||||
	<span slot="header" :class="$style.header"><fa icon="retweet"/>{{ $t('title') }}</span>
 | 
			
		||||
	<mk-renote-form ref="form" :note="note" @posted="onPosted" @canceled="onCanceled" v-hotkey.global="keymap"/>
 | 
			
		||||
</mk-window>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/renote-form-window.vue'),
 | 
			
		||||
	props: {
 | 
			
		||||
		note: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
 
 | 
			
		||||
@@ -3,9 +3,9 @@
 | 
			
		||||
	<mk-note-preview class="preview" :note="note"/>
 | 
			
		||||
	<template v-if="!quote">
 | 
			
		||||
		<footer>
 | 
			
		||||
			<a class="quote" v-if="!quote" @click="onQuote">%i18n:@quote%</a>
 | 
			
		||||
			<ui-button class="button cancel" inline @click="cancel">%i18n:@cancel%</ui-button>
 | 
			
		||||
			<ui-button class="button ok" inline primary @click="ok" :disabled="wait">{{ wait ? '%i18n:@reposting%' : '%i18n:@renote%' }}</ui-button>
 | 
			
		||||
			<a class="quote" v-if="!quote" @click="onQuote">{{ $t('quote') }}</a>
 | 
			
		||||
			<ui-button class="button cancel" inline @click="cancel">{{ $t('cancel') }}</ui-button>
 | 
			
		||||
			<ui-button class="button ok" inline primary @click="ok" :disabled="wait">{{ wait ? this.$t('reposting') : this.$t('renote') }}</ui-button>
 | 
			
		||||
		</footer>
 | 
			
		||||
	</template>
 | 
			
		||||
	<template v-if="quote">
 | 
			
		||||
@@ -16,8 +16,10 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/renote-form.vue'),
 | 
			
		||||
	props: ['note'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
@@ -32,9 +34,9 @@ export default Vue.extend({
 | 
			
		||||
				renoteId: this.note.id
 | 
			
		||||
			}).then(data => {
 | 
			
		||||
				this.$emit('posted');
 | 
			
		||||
				(this as any).apis.notify('%i18n:@success%');
 | 
			
		||||
				(this as any).apis.notify(this.$t('success'));
 | 
			
		||||
			}).catch(err => {
 | 
			
		||||
				(this as any).apis.notify('%i18n:@failure%');
 | 
			
		||||
				(this as any).apis.notify(this.$t('failure'));
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				this.wait = false;
 | 
			
		||||
			});
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,15 @@
 | 
			
		||||
<template>
 | 
			
		||||
<mk-window ref="window" is-modal width="700px" height="550px" @closed="destroyDom">
 | 
			
		||||
	<span slot="header" :class="$style.header"><fa icon="cog"/>%i18n:@settings%</span>
 | 
			
		||||
	<span slot="header" :class="$style.header"><fa icon="cog"/>{{ $t('settings') }}</span>
 | 
			
		||||
	<mk-settings :initial-page="initialPage" @done="close"/>
 | 
			
		||||
</mk-window>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/settings-window.vue'),
 | 
			
		||||
	props: {
 | 
			
		||||
		initialPage: {
 | 
			
		||||
			type: String,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,30 +1,32 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="2fa">
 | 
			
		||||
	<p style="margin-top:0;">%i18n:@intro%<a href="%i18n:@url%" target="_blank">%i18n:@detail%</a></p>
 | 
			
		||||
	<ui-info warn>%i18n:@caution%</ui-info>
 | 
			
		||||
	<p v-if="!data && !$store.state.i.twoFactorEnabled"><ui-button @click="register">%i18n:@register%</ui-button></p>
 | 
			
		||||
	<p style="margin-top:0;">{{ $t('intro') }}<a :href="$t('href')" target="_blank">{{ $t('detail') }}</a></p>
 | 
			
		||||
	<ui-info warn>{{ $t('caution') }}</ui-info>
 | 
			
		||||
	<p v-if="!data && !$store.state.i.twoFactorEnabled"><ui-button @click="register">{{ $t('register') }}</ui-button></p>
 | 
			
		||||
	<template v-if="$store.state.i.twoFactorEnabled">
 | 
			
		||||
		<p>%i18n:@already-registered%</p>
 | 
			
		||||
		<ui-button @click="unregister">%i18n:@unregister%</ui-button>
 | 
			
		||||
		<p>{{ $t('already-registered') }}</p>
 | 
			
		||||
		<ui-button @click="unregister">{{ $t('unregister') }}</ui-button>
 | 
			
		||||
	</template>
 | 
			
		||||
	<div v-if="data">
 | 
			
		||||
		<ol>
 | 
			
		||||
			<li>%i18n:@authenticator% <a href="https://support.google.com/accounts/answer/1066447" target="_blank">%i18n:@howtoinstall%</a></li>
 | 
			
		||||
			<li>%i18n:@scan%<br><img :src="data.qr"></li>
 | 
			
		||||
			<li>%i18n:@done%<br>
 | 
			
		||||
			<li>{{ $t('authenticator% <a href="https://support.google.com/accounts/answer/1066447" target="_blank">%i18n:@howtoinstall') }}</a></li>
 | 
			
		||||
			<li>{{ $t('scan') }}<br><img :src="data.qr"></li>
 | 
			
		||||
			<li>{{ $t('done') }}<br>
 | 
			
		||||
				<input type="number" v-model="token" class="ui">
 | 
			
		||||
				<ui-button primary @click="submit">%i18n:@submit%</ui-button>
 | 
			
		||||
				<ui-button primary @click="submit">{{ $t('submit') }}</ui-button>
 | 
			
		||||
			</li>
 | 
			
		||||
		</ol>
 | 
			
		||||
		<div class="ui info"><p><fa icon="info-circle"/>%i18n:@info%</p></div>
 | 
			
		||||
		<div class="ui info"><p><fa icon="info-circle"/>{{ $t('info') }}</p></div>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/settings.2fa.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			data: null,
 | 
			
		||||
@@ -34,7 +36,7 @@ export default Vue.extend({
 | 
			
		||||
	methods: {
 | 
			
		||||
		register() {
 | 
			
		||||
			(this as any).apis.input({
 | 
			
		||||
				title: '%i18n:@enter-password%',
 | 
			
		||||
				title: this.$t('enter-password'),
 | 
			
		||||
				type: 'password'
 | 
			
		||||
			}).then(password => {
 | 
			
		||||
				(this as any).api('i/2fa/register', {
 | 
			
		||||
@@ -47,13 +49,13 @@ export default Vue.extend({
 | 
			
		||||
 | 
			
		||||
		unregister() {
 | 
			
		||||
			(this as any).apis.input({
 | 
			
		||||
				title: '%i18n:@enter-password%',
 | 
			
		||||
				title: this.$t('enter-password'),
 | 
			
		||||
				type: 'password'
 | 
			
		||||
			}).then(password => {
 | 
			
		||||
				(this as any).api('i/2fa/unregister', {
 | 
			
		||||
					password: password
 | 
			
		||||
				}).then(() => {
 | 
			
		||||
					(this as any).apis.notify('%i18n:@unregistered%');
 | 
			
		||||
					(this as any).apis.notify(this.$t('unregistered'));
 | 
			
		||||
					this.$store.state.i.twoFactorEnabled = false;
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
@@ -63,10 +65,10 @@ export default Vue.extend({
 | 
			
		||||
			(this as any).api('i/2fa/done', {
 | 
			
		||||
				token: this.token
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
				(this as any).apis.notify('%i18n:@success%');
 | 
			
		||||
				(this as any).apis.notify(this.$t('success'));
 | 
			
		||||
				this.$store.state.i.twoFactorEnabled = true;
 | 
			
		||||
			}).catch(() => {
 | 
			
		||||
				(this as any).apis.notify('%i18n:@failed%');
 | 
			
		||||
				(this as any).apis.notify(this.$t('failed'));
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="root">
 | 
			
		||||
	<ui-info v-if="!fetching && apps.length == 0">%i18n:@no-apps%</ui-info>
 | 
			
		||||
	<ui-info v-if="!fetching && apps.length == 0">{{ $t('no-apps') }}</ui-info>
 | 
			
		||||
	<div class="apps" v-if="apps.length != 0">
 | 
			
		||||
		<div v-for="app in apps">
 | 
			
		||||
			<p><b>{{ app.name }}</b></p>
 | 
			
		||||
@@ -12,7 +12,9 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/settings.apps.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
 
 | 
			
		||||
@@ -2,22 +2,24 @@
 | 
			
		||||
<div class="vfcitkilproprqtbnpoertpsziierwzi">
 | 
			
		||||
	<div v-for="timeline in timelines" class="timeline">
 | 
			
		||||
		<ui-input v-model="timeline.title" @change="save">
 | 
			
		||||
			<span>%i18n:@title%</span>
 | 
			
		||||
			<span>{{ $t('title') }}</span>
 | 
			
		||||
		</ui-input>
 | 
			
		||||
		<ui-textarea :value="timeline.query ? timeline.query.map(tags => tags.join(' ')).join('\n') : ''" @input="onQueryChange(timeline, $event)">
 | 
			
		||||
			<span>%i18n:@query%</span>
 | 
			
		||||
			<span>{{ $t('query') }}</span>
 | 
			
		||||
		</ui-textarea>
 | 
			
		||||
		<ui-button class="save" @click="save">%i18n:@save%</ui-button>
 | 
			
		||||
		<ui-button class="save" @click="save">{{ $t('save') }}</ui-button>
 | 
			
		||||
	</div>
 | 
			
		||||
	<ui-button class="add" @click="add">%i18n:@add%</ui-button>
 | 
			
		||||
	<ui-button class="add" @click="add">{{ $t('add') }}</ui-button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import * as uuid from 'uuid';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/settings.tags.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			timelines: this.$store.state.settings.tagTimelines
 | 
			
		||||
 
 | 
			
		||||
@@ -1,31 +1,31 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-settings">
 | 
			
		||||
	<div class="nav">
 | 
			
		||||
		<p :class="{ active: page == 'profile' }" @mousedown="page = 'profile'"><fa icon="user" fixed-width/>%i18n:@profile%</p>
 | 
			
		||||
		<p :class="{ active: page == 'theme' }" @mousedown="page = 'theme'"><fa icon="palette" fixed-width/>%i18n:@theme%</p>
 | 
			
		||||
		<p :class="{ active: page == 'profile' }" @mousedown="page = 'profile'"><fa icon="user" fixed-width/>{{ $t('profile') }}</p>
 | 
			
		||||
		<p :class="{ active: page == 'theme' }" @mousedown="page = 'theme'"><fa icon="palette" fixed-width/>{{ $t('theme') }}</p>
 | 
			
		||||
		<p :class="{ active: page == 'web' }" @mousedown="page = 'web'"><fa icon="desktop" fixed-width/>Web</p>
 | 
			
		||||
		<p :class="{ active: page == 'notification' }" @mousedown="page = 'notification'"><fa :icon="['far', 'bell']" fixed-width/>%i18n:@notification%</p>
 | 
			
		||||
		<p :class="{ active: page == 'drive' }" @mousedown="page = 'drive'"><fa icon="cloud" fixed-width/>%i18n:common.drive%</p>
 | 
			
		||||
		<p :class="{ active: page == 'hashtags' }" @mousedown="page = 'hashtags'"><fa icon="hashtag" fixed-width/>%i18n:@tags%</p>
 | 
			
		||||
		<p :class="{ active: page == 'muteAndBlock' }" @mousedown="page = 'muteAndBlock'"><fa icon="ban" fixed-width/>%i18n:@mute-and-block%</p>
 | 
			
		||||
		<p :class="{ active: page == 'apps' }" @mousedown="page = 'apps'"><fa icon="puzzle-piece" fixed-width/>%i18n:@apps%</p>
 | 
			
		||||
		<p :class="{ active: page == 'security' }" @mousedown="page = 'security'"><fa icon="unlock-alt" fixed-width/>%i18n:@security%</p>
 | 
			
		||||
		<p :class="{ active: page == 'notification' }" @mousedown="page = 'notification'"><fa :icon="['far', 'bell']" fixed-width/>{{ $t('notification') }}</p>
 | 
			
		||||
		<p :class="{ active: page == 'drive' }" @mousedown="page = 'drive'"><fa icon="cloud" fixed-width/>{{ $t('@.drive') }}</p>
 | 
			
		||||
		<p :class="{ active: page == 'hashtags' }" @mousedown="page = 'hashtags'"><fa icon="hashtag" fixed-width/>{{ $t('tags') }}</p>
 | 
			
		||||
		<p :class="{ active: page == 'muteAndBlock' }" @mousedown="page = 'muteAndBlock'"><fa icon="ban" fixed-width/>{{ $t('mute-and-block') }}</p>
 | 
			
		||||
		<p :class="{ active: page == 'apps' }" @mousedown="page = 'apps'"><fa icon="puzzle-piece" fixed-width/>{{ $t('apps') }}</p>
 | 
			
		||||
		<p :class="{ active: page == 'security' }" @mousedown="page = 'security'"><fa icon="unlock-alt" fixed-width/>{{ $t('security') }}</p>
 | 
			
		||||
		<p :class="{ active: page == 'api' }" @mousedown="page = 'api'"><fa icon="key" fixed-width/>API</p>
 | 
			
		||||
		<p :class="{ active: page == 'other' }" @mousedown="page = 'other'"><fa icon="cogs" fixed-width/>%i18n:@other%</p>
 | 
			
		||||
		<p :class="{ active: page == 'other' }" @mousedown="page = 'other'"><fa icon="cogs" fixed-width/>{{ $t('other') }}</p>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="pages">
 | 
			
		||||
		<div class="profile" v-show="page == 'profile'">
 | 
			
		||||
			<mk-profile-editor/>
 | 
			
		||||
 | 
			
		||||
			<ui-card>
 | 
			
		||||
				<div slot="title"><fa :icon="['fab', 'twitter']"/> %i18n:@twitter%</div>
 | 
			
		||||
				<div slot="title"><fa :icon="['fab', 'twitter']"/> {{ $t('twitter') }}</div>
 | 
			
		||||
				<section>
 | 
			
		||||
					<mk-twitter-setting/>
 | 
			
		||||
				</section>
 | 
			
		||||
			</ui-card>
 | 
			
		||||
 | 
			
		||||
			<ui-card>
 | 
			
		||||
				<div slot="title"><fa :icon="['fab', 'github']"/> %i18n:@github%</div>
 | 
			
		||||
				<div slot="title"><fa :icon="['fab', 'github']"/> {{ $t('github') }}</div>
 | 
			
		||||
				<section>
 | 
			
		||||
					<mk-github-setting/>
 | 
			
		||||
				</section>
 | 
			
		||||
@@ -33,7 +33,7 @@
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="theme" v-show="page == 'theme'">
 | 
			
		||||
			<div slot="title"><fa icon="palette"/> %i18n:@theme%</div>
 | 
			
		||||
			<div slot="title"><fa icon="palette"/> {{ $t('theme') }}</div>
 | 
			
		||||
 | 
			
		||||
			<section>
 | 
			
		||||
				<mk-theme/>
 | 
			
		||||
@@ -41,158 +41,153 @@
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="web" v-show="page == 'web'">
 | 
			
		||||
			<div slot="title"><fa icon="sliders-h"/> %i18n:@behaviour%</div>
 | 
			
		||||
			<div slot="title"><fa icon="sliders-h"/> {{ $t('behaviour') }}</div>
 | 
			
		||||
 | 
			
		||||
			<section>
 | 
			
		||||
				<ui-switch v-model="fetchOnScroll">
 | 
			
		||||
					%i18n:@fetch-on-scroll%
 | 
			
		||||
					<span slot="desc">%i18n:@fetch-on-scroll-desc%</span>
 | 
			
		||||
				<ui-switch v-model="fetchOnScroll">{{ $t('fetch-on-scroll') }}
 | 
			
		||||
					<span slot="desc">{{ $t('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 v-model="autoPopout">{{ $t('auto-popout') }}
 | 
			
		||||
					<span slot="desc">{{ $t('auto-popout-desc') }}</span>
 | 
			
		||||
				</ui-switch>
 | 
			
		||||
				<ui-switch v-model="deckNav">%i18n:@deck-nav%<span slot="desc">%i18n:@deck-nav-desc%</span></ui-switch>
 | 
			
		||||
				<ui-switch v-model="deckNav">{{ $t('deck-nav') }}<span slot="desc">{{ $t('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>
 | 
			
		||||
					<summary>{{ $t('advanced') }}</summary>
 | 
			
		||||
					<ui-switch v-model="apiViaStream">{{ $t('api-via-stream') }}
 | 
			
		||||
						<span slot="desc">{{ $t('api-via-stream-desc') }}</span>
 | 
			
		||||
					</ui-switch>
 | 
			
		||||
				</details>
 | 
			
		||||
			</section>
 | 
			
		||||
 | 
			
		||||
			<section>
 | 
			
		||||
				<header>%i18n:@timeline%</header>
 | 
			
		||||
				<ui-switch v-model="showMyRenotes">%i18n:@show-my-renotes%</ui-switch>
 | 
			
		||||
				<ui-switch v-model="showRenotedMyNotes">%i18n:@show-renoted-my-notes%</ui-switch>
 | 
			
		||||
				<ui-switch v-model="showLocalRenotes">%i18n:@show-local-renotes%</ui-switch>
 | 
			
		||||
				<header>{{ $t('timeline') }}</header>
 | 
			
		||||
				<ui-switch v-model="showMyRenotes">{{ $t('show-my-renotes') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="showRenotedMyNotes">{{ $t('show-renoted-my-notes') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="showLocalRenotes">{{ $t('show-local-renotes') }}</ui-switch>
 | 
			
		||||
			</section>
 | 
			
		||||
 | 
			
		||||
			<section>
 | 
			
		||||
				<header>%i18n:@note-visibility%</header>
 | 
			
		||||
				<ui-switch v-model="rememberNoteVisibility">%i18n:@remember-note-visibility%</ui-switch>
 | 
			
		||||
				<header>{{ $t('note-visibility') }}</header>
 | 
			
		||||
				<ui-switch v-model="rememberNoteVisibility">{{ $t('remember-note-visibility') }}</ui-switch>
 | 
			
		||||
				<section>
 | 
			
		||||
					<header>%i18n:@default-note-visibility%</header>
 | 
			
		||||
					<header>{{ $t('default-note-visibility') }}</header>
 | 
			
		||||
					<ui-select v-model="defaultNoteVisibility">
 | 
			
		||||
						<option value="public">%i18n:common.note-visibility.public%</option>
 | 
			
		||||
						<option value="home">%i18n:common.note-visibility.home%</option>
 | 
			
		||||
						<option value="followers">%i18n:common.note-visibility.followers%</option>
 | 
			
		||||
						<option value="specified">%i18n:common.note-visibility.specified%</option>
 | 
			
		||||
						<option value="private">%i18n:common.note-visibility.private%</option>
 | 
			
		||||
						<option value="public">{{ $t('@.note-visibility.public') }}</option>
 | 
			
		||||
						<option value="home">{{ $t('@.note-visibility.home') }}</option>
 | 
			
		||||
						<option value="followers">{{ $t('@.note-visibility.followers') }}</option>
 | 
			
		||||
						<option value="specified">{{ $t('@.note-visibility.specified') }}</option>
 | 
			
		||||
						<option value="private">{{ $t('@.note-visibility.private') }}</option>
 | 
			
		||||
					</ui-select>
 | 
			
		||||
				</section>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="web" v-show="page == 'web'">
 | 
			
		||||
			<div slot="title"><fa icon="desktop"/> %i18n:@display%</div>
 | 
			
		||||
			<div slot="title"><fa icon="desktop"/> {{ $t('display') }}</div>
 | 
			
		||||
 | 
			
		||||
			<section>
 | 
			
		||||
				<ui-switch v-model="showPostFormOnTopOfTl">%i18n:@post-form-on-timeline%</ui-switch>
 | 
			
		||||
				<ui-button @click="customizeHome">%i18n:@customize%</ui-button>
 | 
			
		||||
				<ui-switch v-model="showPostFormOnTopOfTl">{{ $t('post-form-on-timeline') }}</ui-switch>
 | 
			
		||||
				<ui-button @click="customizeHome">{{ $t('customize') }}</ui-button>
 | 
			
		||||
			</section>
 | 
			
		||||
			<section>
 | 
			
		||||
				<header>%i18n:@wallpaper%</header>
 | 
			
		||||
				<ui-button @click="updateWallpaper">%i18n:@choose-wallpaper%</ui-button>
 | 
			
		||||
				<ui-button @click="deleteWallpaper">%i18n:@delete-wallpaper%</ui-button>
 | 
			
		||||
				<header>{{ $t('wallpaper') }}</header>
 | 
			
		||||
				<ui-button @click="updateWallpaper">{{ $t('choose-wallpaper') }}</ui-button>
 | 
			
		||||
				<ui-button @click="deleteWallpaper">{{ $t('delete-wallpaper') }}</ui-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>
 | 
			
		||||
				<header>{{ $t('navbar-position') }}</header>
 | 
			
		||||
				<ui-radio v-model="navbar" value="top">{{ $t('navbar-position-top') }}</ui-radio>
 | 
			
		||||
				<ui-radio v-model="navbar" value="left">{{ $t('navbar-position-left') }}</ui-radio>
 | 
			
		||||
				<ui-radio v-model="navbar" value="right">{{ $t('navbar-position-right') }}</ui-radio>
 | 
			
		||||
			</section>
 | 
			
		||||
			<section>
 | 
			
		||||
				<ui-switch v-model="deckDefault">%i18n:@deck-default%</ui-switch>
 | 
			
		||||
				<ui-switch v-model="deckDefault">{{ $t('deck-default') }}</ui-switch>
 | 
			
		||||
			</section>
 | 
			
		||||
			<section>
 | 
			
		||||
				<ui-switch v-model="darkmode">%i18n:@dark-mode%</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="circleIcons">%i18n:@circle-icons%</ui-switch>
 | 
			
		||||
				<ui-switch v-model="reduceMotion">%i18n:common.reduce-motion%</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="useOsDefaultEmojis">%i18n:common.use-os-default-emojis%</ui-switch>
 | 
			
		||||
				<ui-switch v-model="iLikeSushi">%i18n:common.i-like-sushi%</ui-switch>
 | 
			
		||||
				<ui-switch v-model="darkmode">{{ $t('dark-mode') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="useShadow">{{ $t('use-shadow') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="roundedCorners">{{ $t('rounded-corners') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="circleIcons">{{ $t('circle-icons') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="reduceMotion">{{ $t('@.reduce-motion') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="contrastedAcct">{{ $t('contrasted-acct') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="showFullAcct">{{ $t('@.show-full-acct') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="useOsDefaultEmojis">{{ $t('@.use-os-default-emojis') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="iLikeSushi">{{ $t('@.i-like-sushi') }}</ui-switch>
 | 
			
		||||
			</section>
 | 
			
		||||
			<section>
 | 
			
		||||
				<ui-switch v-model="suggestRecentHashtags">%i18n:@suggest-recent-hashtags%</ui-switch>
 | 
			
		||||
				<ui-switch v-model="showClockOnHeader">%i18n:@show-clock-on-header%</ui-switch>
 | 
			
		||||
				<ui-switch v-model="alwaysShowNsfw">%i18n:common.always-show-nsfw%</ui-switch>
 | 
			
		||||
				<ui-switch v-model="showReplyTarget">%i18n:@show-reply-target%</ui-switch>
 | 
			
		||||
				<ui-switch v-model="showMaps">%i18n:@show-maps%</ui-switch>
 | 
			
		||||
				<ui-switch v-model="disableAnimatedMfm">%i18n:common.disable-animated-mfm%</ui-switch>
 | 
			
		||||
				<ui-switch v-model="suggestRecentHashtags">{{ $t('suggest-recent-hashtags') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="showClockOnHeader">{{ $t('show-clock-on-header') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="alwaysShowNsfw">{{ $t('@.always-show-nsfw') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="showReplyTarget">{{ $t('show-reply-target') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="showMaps">{{ $t('show-maps') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="disableAnimatedMfm">{{ $t('@.disable-animated-mfm') }}</ui-switch>
 | 
			
		||||
			</section>
 | 
			
		||||
			<section>
 | 
			
		||||
				<header>%i18n:@deck-column-align%</header>
 | 
			
		||||
				<ui-radio v-model="deckColumnAlign" value="center">%i18n:@deck-column-align-center%</ui-radio>
 | 
			
		||||
				<ui-radio v-model="deckColumnAlign" value="left">%i18n:@deck-column-align-left%</ui-radio>
 | 
			
		||||
				<header>{{ $t('deck-column-align') }}</header>
 | 
			
		||||
				<ui-radio v-model="deckColumnAlign" value="center">{{ $t('deck-column-align-center') }}</ui-radio>
 | 
			
		||||
				<ui-radio v-model="deckColumnAlign" value="left">{{ $t('deck-column-align-left') }}</ui-radio>
 | 
			
		||||
			</section>
 | 
			
		||||
			<section>
 | 
			
		||||
				<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>
 | 
			
		||||
				<ui-switch v-model="games_reversi_showBoardLabels">{{ $t('@.show-reversi-board-labels') }}</ui-switch>
 | 
			
		||||
				<ui-switch v-model="games_reversi_useContrastStones">{{ $t('@.use-contrast-reversi-stones') }}</ui-switch>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="web" v-show="page == 'web'">
 | 
			
		||||
			<div slot="title"><fa icon="volume-up"/> %i18n:@sound%</div>
 | 
			
		||||
			<div slot="title"><fa icon="volume-up"/> {{ $t('sound') }}</div>
 | 
			
		||||
 | 
			
		||||
			<section>
 | 
			
		||||
				<ui-switch v-model="enableSounds">
 | 
			
		||||
					%i18n:@enable-sounds%
 | 
			
		||||
					<span slot="desc">%i18n:@enable-sounds-desc%</span>
 | 
			
		||||
				<ui-switch v-model="enableSounds">{{ $t('enable-sounds') }}
 | 
			
		||||
					<span slot="desc">{{ $t('enable-sounds-desc') }}</span>
 | 
			
		||||
				</ui-switch>
 | 
			
		||||
				<label>%i18n:@volume%</label>
 | 
			
		||||
				<label>{{ $t('volume') }}</label>
 | 
			
		||||
				<input type="range"
 | 
			
		||||
					v-model="soundVolume"
 | 
			
		||||
					:disabled="!enableSounds"
 | 
			
		||||
					max="1"
 | 
			
		||||
					step="0.1"
 | 
			
		||||
				/>
 | 
			
		||||
				<ui-button @click="soundTest"><fa icon="volume-up"/> %i18n:@test%</ui-button>
 | 
			
		||||
				<ui-button @click="soundTest"><fa icon="volume-up"/> {{ $t('test') }}</ui-button>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="web" v-show="page == 'web'">
 | 
			
		||||
			<div slot="title"><fa icon="language"/> %i18n:@language%</div>
 | 
			
		||||
			<div slot="title"><fa icon="language"/> {{ $t('language') }}</div>
 | 
			
		||||
			<section class="fit-top">
 | 
			
		||||
				<ui-select v-model="lang" placeholder="%i18n:@pick-language%">
 | 
			
		||||
					<optgroup label="%i18n:@recommended%">
 | 
			
		||||
						<option value="">%i18n:@auto%</option>
 | 
			
		||||
				<ui-select v-model="lang" :placeholder="$t('placeholder')">
 | 
			
		||||
					<optgroup :label="$t('label')">
 | 
			
		||||
						<option value="">{{ $t('auto') }}</option>
 | 
			
		||||
					</optgroup>
 | 
			
		||||
 | 
			
		||||
					<optgroup label="%i18n:@specify-language%">
 | 
			
		||||
					<optgroup :label="$t('label')">
 | 
			
		||||
						<option v-for="x in langs" :value="x[0]" :key="x[0]">{{ x[1] }}</option>
 | 
			
		||||
					</optgroup>
 | 
			
		||||
				</ui-select>
 | 
			
		||||
				<div class="none ui info">
 | 
			
		||||
					<p><fa icon="info-circle"/>%i18n:@language-desc%</p>
 | 
			
		||||
					<p><fa icon="info-circle"/>{{ $t('language-desc') }}</p>
 | 
			
		||||
				</div>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="web" v-show="page == 'web'">
 | 
			
		||||
			<div slot="title"><fa :icon="['far', 'trash-alt']"/> %i18n:@cache%</div>
 | 
			
		||||
			<div slot="title"><fa :icon="['far', 'trash-alt']"/> {{ $t('cache') }}</div>
 | 
			
		||||
			<section>
 | 
			
		||||
				<ui-button @click="clean">%i18n:@clean-cache%</ui-button>
 | 
			
		||||
				<ui-button @click="clean">{{ $t('clean-cache') }}</ui-button>
 | 
			
		||||
				<div class="none ui info warn">
 | 
			
		||||
					<p><fa icon="exclamation-triangle"/>%i18n:@cache-warn%</p>
 | 
			
		||||
					<p><fa icon="exclamation-triangle"/>{{ $t('cache-warn') }}</p>
 | 
			
		||||
				</div>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="notification" v-show="page == 'notification'">
 | 
			
		||||
			<div slot="title"><fa :icon="['far', 'bell']"/> %i18n:@notification%</div>
 | 
			
		||||
			<div slot="title"><fa :icon="['far', 'bell']"/> {{ $t('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>
 | 
			
		||||
					{{ $t('auto-watch') }}<span slot="desc">{{ $t('auto-watch-desc') }}</span>
 | 
			
		||||
				</ui-switch>
 | 
			
		||||
				<section>
 | 
			
		||||
					<ui-button @click="readAllUnreadNotes">%i18n:@mark-as-read-all-unread-notes%</ui-button>
 | 
			
		||||
					<ui-button @click="readAllUnreadNotes">{{ $t('mark-as-read-all-unread-notes') }}</ui-button>
 | 
			
		||||
				</section>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
@@ -202,7 +197,7 @@
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="hashtags" v-show="page == 'hashtags'">
 | 
			
		||||
			<div slot="title"><fa icon="hashtag"/> %i18n:@tags%</div>
 | 
			
		||||
			<div slot="title"><fa icon="hashtag"/> {{ $t('tags') }}</div>
 | 
			
		||||
			<section>
 | 
			
		||||
				<x-tags/>
 | 
			
		||||
			</section>
 | 
			
		||||
@@ -213,28 +208,28 @@
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="apps" v-show="page == 'apps'">
 | 
			
		||||
			<div slot="title"><fa icon="puzzle-piece"/> %i18n:@apps%</div>
 | 
			
		||||
			<div slot="title"><fa icon="puzzle-piece"/> {{ $t('apps') }}</div>
 | 
			
		||||
			<section>
 | 
			
		||||
				<x-apps/>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="password" v-show="page == 'security'">
 | 
			
		||||
			<div slot="title"><fa icon="unlock-alt"/> %i18n:@password%</div>
 | 
			
		||||
			<div slot="title"><fa icon="unlock-alt"/> {{ $t('password') }}</div>
 | 
			
		||||
			<section>
 | 
			
		||||
				<mk-password-settings/>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="2fa" v-show="page == 'security'">
 | 
			
		||||
			<div slot="title"><fa icon="mobile-alt"/> %i18n:@2fa%</div>
 | 
			
		||||
			<div slot="title"><fa icon="mobile-alt"/> {{ $t('2fa') }}</div>
 | 
			
		||||
			<section>
 | 
			
		||||
				<x-2fa/>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="signin" v-show="page == 'security'">
 | 
			
		||||
			<div slot="title"><fa icon="sign-in-alt"/> %i18n:@signin%</div>
 | 
			
		||||
			<div slot="title"><fa icon="sign-in-alt"/> {{ $t('signin') }}</div>
 | 
			
		||||
			<section>
 | 
			
		||||
				<x-signins/>
 | 
			
		||||
			</section>
 | 
			
		||||
@@ -245,46 +240,43 @@
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="other" v-show="page == 'other'">
 | 
			
		||||
			<div slot="title"><fa icon="info-circle"/> %i18n:@about%</div>
 | 
			
		||||
			<div slot="title"><fa icon="info-circle"/> {{ $t('about') }}</div>
 | 
			
		||||
			<section>
 | 
			
		||||
				<p v-if="meta">%i18n:@operator%: <i><a :href="'mailto:' + meta.maintainer.email" target="_blank">{{ meta.maintainer.name }}</a></i></p>
 | 
			
		||||
				<p v-if="meta">{{ $t('operator') }}: <i><a :href="'mailto:' + meta.maintainer.email" target="_blank">{{ meta.maintainer.name }}</a></i></p>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="other" v-show="page == 'other'">
 | 
			
		||||
			<div slot="title"><fa icon="sync-alt"/> %i18n:@update%</div>
 | 
			
		||||
			<div slot="title"><fa icon="sync-alt"/> {{ $t('update') }}</div>
 | 
			
		||||
			<section>
 | 
			
		||||
				<p>
 | 
			
		||||
					<span>%i18n:@version% <i>{{ version }}</i></span>
 | 
			
		||||
					<span>{{ $t('version') }} <i>{{ version }}</i></span>
 | 
			
		||||
					<template v-if="latestVersion !== undefined">
 | 
			
		||||
						<br>
 | 
			
		||||
						<span>%i18n:@latest-version% <i>{{ latestVersion ? latestVersion : version }}</i></span>
 | 
			
		||||
						<span>{{ $t('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>
 | 
			
		||||
					<template v-if="checkingForUpdate">{{ $t('update-checking') }}<mk-ellipsis/></template>
 | 
			
		||||
					<template v-else>{{ $t('do-update') }}</template>
 | 
			
		||||
				</button>
 | 
			
		||||
				<details>
 | 
			
		||||
					<summary>%i18n:@update-settings%</summary>
 | 
			
		||||
					<summary>{{ $t('update-settings') }}</summary>
 | 
			
		||||
					<ui-switch v-model="preventUpdate">
 | 
			
		||||
						%i18n:@prevent-update%
 | 
			
		||||
						<span slot="desc">%i18n:@prevent-update-desc%</span>
 | 
			
		||||
						{{ $t('prevent-update') }}<span slot="desc">{{ $t('prevent-update-desc') }}</span>
 | 
			
		||||
					</ui-switch>
 | 
			
		||||
				</details>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
 | 
			
		||||
		<ui-card class="other" v-show="page == 'other'">
 | 
			
		||||
			<div slot="title"><fa icon="cogs"/> %i18n:@advanced-settings%</div>
 | 
			
		||||
			<div slot="title"><fa icon="cogs"/> {{ $t('advanced-settings') }}</div>
 | 
			
		||||
			<section>
 | 
			
		||||
				<ui-switch v-model="debug">
 | 
			
		||||
					%i18n:@debug-mode%
 | 
			
		||||
					<span slot="desc">%i18n:@debug-mode-desc%</span>
 | 
			
		||||
					{{ $t('debug-mode') }}<span slot="desc">{{ $t('debug-mode-desc') }}</span>
 | 
			
		||||
				</ui-switch>
 | 
			
		||||
				<ui-switch v-model="enableExperimentalFeatures">
 | 
			
		||||
					%i18n:@experimental%
 | 
			
		||||
					<span slot="desc">%i18n:@experimental-desc%</span>
 | 
			
		||||
					{{ $t('experimental') }}<span slot="desc">{{ $t('experimental-desc') }}</span>
 | 
			
		||||
				</ui-switch>
 | 
			
		||||
			</section>
 | 
			
		||||
		</ui-card>
 | 
			
		||||
@@ -294,6 +286,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import X2fa from './settings.2fa.vue';
 | 
			
		||||
import XApps from './settings.apps.vue';
 | 
			
		||||
import XSignins from './settings.signins.vue';
 | 
			
		||||
@@ -302,6 +295,7 @@ import { url, langs, clientVersion as version } from '../../../config';
 | 
			
		||||
import checkForUpdate from '../../../common/scripts/check-for-update';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/settings.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		X2fa,
 | 
			
		||||
		XApps,
 | 
			
		||||
@@ -544,13 +538,13 @@ export default Vue.extend({
 | 
			
		||||
				this.latestVersion = newer;
 | 
			
		||||
				if (newer == null) {
 | 
			
		||||
					(this as any).apis.dialog({
 | 
			
		||||
						title: '%i18n:@no-updates%',
 | 
			
		||||
						text: '%i18n:@no-updates-desc%'
 | 
			
		||||
						title: this.$t('no-updates'),
 | 
			
		||||
						text: this.$t('no-updates-desc')
 | 
			
		||||
					});
 | 
			
		||||
				} else {
 | 
			
		||||
					(this as any).apis.dialog({
 | 
			
		||||
						title: '%i18n:@update-available%',
 | 
			
		||||
						text: '%i18n:@update-available-desc%'
 | 
			
		||||
						title: this.$t('update-available'),
 | 
			
		||||
						text: this.$t('update-available-desc')
 | 
			
		||||
					});
 | 
			
		||||
				}
 | 
			
		||||
			});
 | 
			
		||||
@@ -558,8 +552,8 @@ export default Vue.extend({
 | 
			
		||||
		clean() {
 | 
			
		||||
			localStorage.clear();
 | 
			
		||||
			(this as any).apis.dialog({
 | 
			
		||||
				title: '%i18n:@cache-cleared%',
 | 
			
		||||
				text: '%i18n:@cache-cleared-desc%'
 | 
			
		||||
				title: this.$t('cache-cleared'),
 | 
			
		||||
				text: this.$t('cache-cleared-desc')
 | 
			
		||||
			});
 | 
			
		||||
		},
 | 
			
		||||
		soundTest() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +1,18 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-sub-note-content">
 | 
			
		||||
	<div class="body">
 | 
			
		||||
		<span v-if="note.isHidden" style="opacity: 0.5">%i18n:@private%</span>
 | 
			
		||||
		<span v-if="note.deletedAt" style="opacity: 0.5">%i18n:@deleted%</span>
 | 
			
		||||
		<span v-if="note.isHidden" style="opacity: 0.5">{{ $t('private') }}</span>
 | 
			
		||||
		<span v-if="note.deletedAt" style="opacity: 0.5">{{ $t('deleted') }}</span>
 | 
			
		||||
		<a class="reply" v-if="note.replyId"><fa icon="reply"/></a>
 | 
			
		||||
		<misskey-flavored-markdown v-if="note.text" :text="note.text" :i="$store.state.i" :customEmojis="note.emojis"/>
 | 
			
		||||
		<misskey-flavored-markdown v-if="note.text" :text="note.text" :i="$store.state.i" :custom-emojis="note.emojis"/>
 | 
			
		||||
		<a class="rp" v-if="note.renoteId" :href="`/notes/${note.renoteId}`">RN: ...</a>
 | 
			
		||||
	</div>
 | 
			
		||||
	<details v-if="note.files.length > 0">
 | 
			
		||||
		<summary>({{ '%i18n:@media-count%'.replace('{}', note.files.length) }})</summary>
 | 
			
		||||
		<summary>({{ this.$t('media-count').replace('{}', note.files.length) }})</summary>
 | 
			
		||||
		<mk-media-list :media-list="note.files"/>
 | 
			
		||||
	</details>
 | 
			
		||||
	<details v-if="note.poll">
 | 
			
		||||
		<summary>%i18n:@poll%</summary>
 | 
			
		||||
		<summary>{{ $t('poll') }}</summary>
 | 
			
		||||
		<mk-poll :note="note"/>
 | 
			
		||||
	</details>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -20,8 +20,10 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/sub-note-content.vue'),
 | 
			
		||||
	props: ['note']
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -4,7 +4,7 @@
 | 
			
		||||
 | 
			
		||||
	<mk-notes ref="timeline" :more="existMore ? more : null">
 | 
			
		||||
		<p :class="$style.empty" slot="empty">
 | 
			
		||||
			<fa :icon="['far', 'comments']"/>%i18n:@empty%
 | 
			
		||||
			<fa :icon="['far', 'comments']"/>{{ $t('empty') }}
 | 
			
		||||
		</p>
 | 
			
		||||
	</mk-notes>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -12,10 +12,12 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
const fetchLimit = 10;
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/timeline.core.vue'),
 | 
			
		||||
	props: {
 | 
			
		||||
		src: {
 | 
			
		||||
			type: String,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,17 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mk-timeline">
 | 
			
		||||
	<header>
 | 
			
		||||
		<span :data-active="src == 'home'" @click="src = 'home'"><fa icon="home"/> %i18n:@home%</span>
 | 
			
		||||
		<span :data-active="src == 'local'" @click="src = 'local'" v-if="enableLocalTimeline"><fa :icon="['far', 'comments']"/> %i18n:@local%</span>
 | 
			
		||||
		<span :data-active="src == 'hybrid'" @click="src = 'hybrid'" v-if="enableLocalTimeline"><fa icon="share-alt"/> %i18n:@hybrid%</span>
 | 
			
		||||
		<span :data-active="src == 'global'" @click="src = 'global'"><fa icon="globe"/> %i18n:@global%</span>
 | 
			
		||||
		<span :data-active="src == 'home'" @click="src = 'home'"><fa icon="home"/> {{ $t('home') }}</span>
 | 
			
		||||
		<span :data-active="src == 'local'" @click="src = 'local'" v-if="enableLocalTimeline"><fa :icon="['far', 'comments']"/> {{ $t('local') }}</span>
 | 
			
		||||
		<span :data-active="src == 'hybrid'" @click="src = 'hybrid'" v-if="enableLocalTimeline"><fa icon="share-alt"/> {{ $t('hybrid') }}</span>
 | 
			
		||||
		<span :data-active="src == 'global'" @click="src = 'global'"><fa icon="globe"/> {{ $t('global') }}</span>
 | 
			
		||||
		<span :data-active="src == 'tag'" @click="src = 'tag'" v-if="tagTl"><fa icon="hashtag"/> {{ tagTl.title }}</span>
 | 
			
		||||
		<span :data-active="src == 'list'" @click="src = 'list'" v-if="list"><fa icon="list"/> {{ list.title }}</span>
 | 
			
		||||
		<div class="buttons">
 | 
			
		||||
			<button :data-active="src == 'mentions'" @click="src = 'mentions'" title="%i18n:@mentions%"><fa icon="at"/><i class="badge" v-if="$store.state.i.hasUnreadMentions"><fa icon="circle"/></i></button>
 | 
			
		||||
			<button :data-active="src == 'messages'" @click="src = 'messages'" title="%i18n:@messages%"><fa :icon="['far', 'envelope']"/><i class="badge" v-if="$store.state.i.hasUnreadSpecifiedNotes"><fa icon="circle"/></i></button>
 | 
			
		||||
			<button @click="chooseTag" title="%i18n:@hashtag%" ref="tagButton"><fa icon="hashtag"/></button>
 | 
			
		||||
			<button @click="chooseList" title="%i18n:@list%" ref="listButton"><fa icon="list"/></button>
 | 
			
		||||
			<button :data-active="src == 'mentions'" @click="src = 'mentions'" :title="$t('mentions')"><fa icon="at"/><i class="badge" v-if="$store.state.i.hasUnreadMentions"><fa icon="circle"/></i></button>
 | 
			
		||||
			<button :data-active="src == 'messages'" @click="src = 'messages'" :title="$t('messages')"><fa :icon="['far', 'envelope']"/><i class="badge" v-if="$store.state.i.hasUnreadSpecifiedNotes"><fa icon="circle"/></i></button>
 | 
			
		||||
			<button @click="chooseTag" :title="$t('hashtag')" ref="tagButton"><fa icon="hashtag"/></button>
 | 
			
		||||
			<button @click="chooseList" :title="$t('list')" ref="listButton"><fa icon="list"/></button>
 | 
			
		||||
		</div>
 | 
			
		||||
	</header>
 | 
			
		||||
	<x-core v-if="src == 'home'" ref="tl" key="home" src="home"/>
 | 
			
		||||
@@ -27,11 +27,13 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import XCore from './timeline.core.vue';
 | 
			
		||||
import Menu from '../../../common/views/components/menu.vue';
 | 
			
		||||
import MkSettingsWindow from './settings-window.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/timeline.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		XCore
 | 
			
		||||
	},
 | 
			
		||||
@@ -105,10 +107,10 @@ export default Vue.extend({
 | 
			
		||||
 | 
			
		||||
			let menu = [{
 | 
			
		||||
				icon: 'plus',
 | 
			
		||||
				text: '%i18n:@add-list%',
 | 
			
		||||
				text: this.$t('add-list'),
 | 
			
		||||
				action: () => {
 | 
			
		||||
					(this as any).apis.input({
 | 
			
		||||
						title: '%i18n:@list-name%',
 | 
			
		||||
						title: this.$t('list-name'),
 | 
			
		||||
					}).then(async title => {
 | 
			
		||||
						const list = await (this as any).api('users/lists/create', {
 | 
			
		||||
							title
 | 
			
		||||
@@ -143,7 +145,7 @@ export default Vue.extend({
 | 
			
		||||
		chooseTag() {
 | 
			
		||||
			let menu = [{
 | 
			
		||||
				icon: 'plus',
 | 
			
		||||
				text: '%i18n:@add-tag-timeline%',
 | 
			
		||||
				text: this.$t('add-tag-timeline'),
 | 
			
		||||
				action: () => {
 | 
			
		||||
					(this as any).os.new(MkSettingsWindow, {
 | 
			
		||||
						initialPage: 'hashtags'
 | 
			
		||||
 
 | 
			
		||||
@@ -10,35 +10,35 @@
 | 
			
		||||
				<li>
 | 
			
		||||
					<router-link :to="`/@${ $store.state.i.username }`">
 | 
			
		||||
						<i><fa icon="user"/></i>
 | 
			
		||||
						<span>%i18n:@profile%</span>
 | 
			
		||||
						<span>{{ $t('profile') }}</span>
 | 
			
		||||
						<i><fa icon="angle-right"/></i>
 | 
			
		||||
					</router-link>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li @click="drive">
 | 
			
		||||
					<p>
 | 
			
		||||
						<i><fa icon="cloud"/></i>
 | 
			
		||||
						<span>%i18n:common.drive%</span>
 | 
			
		||||
						<span>{{ $t('@.drive') }}</span>
 | 
			
		||||
						<i><fa icon="angle-right"/></i>
 | 
			
		||||
					</p>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li>
 | 
			
		||||
					<router-link to="/i/favorites">
 | 
			
		||||
						<i><fa icon="star"/></i>
 | 
			
		||||
						<span>%i18n:@favorites%</span>
 | 
			
		||||
						<span>{{ $t('favorites') }}</span>
 | 
			
		||||
						<i><fa icon="angle-right"/></i>
 | 
			
		||||
					</router-link>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li @click="list">
 | 
			
		||||
					<p>
 | 
			
		||||
						<i><fa icon="list"/></i>
 | 
			
		||||
						<span>%i18n:@lists%</span>
 | 
			
		||||
						<span>{{ $t('lists') }}</span>
 | 
			
		||||
						<i><fa icon="angle-right"/></i>
 | 
			
		||||
					</p>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li @click="followRequests" v-if="($store.state.i.isLocked || $store.state.i.carefulBot)">
 | 
			
		||||
					<p>
 | 
			
		||||
						<i><fa :icon="['far', 'envelope']"/></i>
 | 
			
		||||
						<span>%i18n:@follow-requests%<i v-if="$store.state.i.pendingReceivedFollowRequestsCount">{{ $store.state.i.pendingReceivedFollowRequestsCount }}</i></span>
 | 
			
		||||
						<span>{{ $t('follow-requests') }}<i v-if="$store.state.i.pendingReceivedFollowRequestsCount">{{ $store.state.i.pendingReceivedFollowRequestsCount }}</i></span>
 | 
			
		||||
						<i><fa icon="angle-right"/></i>
 | 
			
		||||
					</p>
 | 
			
		||||
				</li>
 | 
			
		||||
@@ -47,21 +47,21 @@
 | 
			
		||||
				<li>
 | 
			
		||||
					<router-link to="/i/customize-home">
 | 
			
		||||
						<i><fa icon="wrench"/></i>
 | 
			
		||||
						<span>%i18n:@customize%</span>
 | 
			
		||||
						<span>{{ $t('customize') }}</span>
 | 
			
		||||
						<i><fa icon="angle-right"/></i>
 | 
			
		||||
					</router-link>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li @click="settings">
 | 
			
		||||
					<p>
 | 
			
		||||
						<i><fa icon="cog"/></i>
 | 
			
		||||
						<span>%i18n:@settings%</span>
 | 
			
		||||
						<span>{{ $t('settings') }}</span>
 | 
			
		||||
						<i><fa icon="angle-right"/></i>
 | 
			
		||||
					</p>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li v-if="$store.state.i.isAdmin">
 | 
			
		||||
					<a href="/admin">
 | 
			
		||||
						<i><fa icon="terminal"/></i>
 | 
			
		||||
						<span>%i18n:@admin%</span>
 | 
			
		||||
						<span>{{ $t('admin') }}</span>
 | 
			
		||||
						<i><fa icon="angle-right"/></i>
 | 
			
		||||
					</a>
 | 
			
		||||
				</li>
 | 
			
		||||
@@ -69,7 +69,7 @@
 | 
			
		||||
			<ul>
 | 
			
		||||
				<li @click="dark">
 | 
			
		||||
					<p>
 | 
			
		||||
						<span>%i18n:@dark%</span>
 | 
			
		||||
						<span>{{ $t('dark') }}</span>
 | 
			
		||||
						<template v-if="$store.state.device.darkmode"><i><fa icon="moon"/></i></template>
 | 
			
		||||
						<template v-else><i><fa :icon="['far', 'moon']"/></i></template>
 | 
			
		||||
					</p>
 | 
			
		||||
@@ -79,7 +79,7 @@
 | 
			
		||||
				<li @click="signout">
 | 
			
		||||
					<p class="signout">
 | 
			
		||||
						<i><fa icon="power-off"/></i>
 | 
			
		||||
						<span>%i18n:@signout%</span>
 | 
			
		||||
						<span>{{ $t('signout') }}</span>
 | 
			
		||||
					</p>
 | 
			
		||||
				</li>
 | 
			
		||||
			</ul>
 | 
			
		||||
@@ -90,6 +90,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import MkUserListsWindow from './user-lists-window.vue';
 | 
			
		||||
import MkFollowRequestsWindow from './received-follow-requests-window.vue';
 | 
			
		||||
import MkSettingsWindow from './settings-window.vue';
 | 
			
		||||
@@ -97,6 +98,7 @@ import MkDriveWindow from './drive-window.vue';
 | 
			
		||||
import contains from '../../../common/scripts/contains';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/ui.header.account.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			isOpen: false
 | 
			
		||||
 
 | 
			
		||||
@@ -4,31 +4,31 @@
 | 
			
		||||
		<template v-if="$store.getters.isSignedIn">
 | 
			
		||||
			<template v-if="$store.state.device.deckDefault">
 | 
			
		||||
				<li class="deck" :class="{ active: $route.name == 'deck' || $route.name == 'index' }" @click="goToTop">
 | 
			
		||||
					<router-link to="/"><fa icon="columns"/><p>%i18n:@deck%</p></router-link>
 | 
			
		||||
					<router-link to="/"><fa icon="columns"/><p>{{ $t('deck') }}</p></router-link>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li class="home" :class="{ active: $route.name == 'home' }" @click="goToTop">
 | 
			
		||||
					<router-link to="/home"><fa icon="home"/><p>%i18n:@home%</p></router-link>
 | 
			
		||||
					<router-link to="/home"><fa icon="home"/><p>{{ $t('home') }}</p></router-link>
 | 
			
		||||
				</li>
 | 
			
		||||
			</template>
 | 
			
		||||
			<template v-else>
 | 
			
		||||
				<li class="home" :class="{ active: $route.name == 'home' || $route.name == 'index' }" @click="goToTop">
 | 
			
		||||
					<router-link to="/"><fa icon="home"/><p>%i18n:@home%</p></router-link>
 | 
			
		||||
					<router-link to="/"><fa icon="home"/><p>{{ $t('home') }}</p></router-link>
 | 
			
		||||
				</li>
 | 
			
		||||
				<li class="deck" :class="{ active: $route.name == 'deck' }" @click="goToTop">
 | 
			
		||||
					<router-link to="/deck"><fa icon="columns"/><p>%i18n:@deck%</p></router-link>
 | 
			
		||||
					<router-link to="/deck"><fa icon="columns"/><p>{{ $t('deck') }}</p></router-link>
 | 
			
		||||
				</li>
 | 
			
		||||
			</template>
 | 
			
		||||
			<li class="messaging">
 | 
			
		||||
				<a @click="messaging">
 | 
			
		||||
					<fa icon="comments"/>
 | 
			
		||||
					<p>%i18n:@messaging%</p>
 | 
			
		||||
					<p>{{ $t('@.messaging') }}</p>
 | 
			
		||||
					<template v-if="hasUnreadMessagingMessage"><fa icon="circle"/></template>
 | 
			
		||||
				</a>
 | 
			
		||||
			</li>
 | 
			
		||||
			<li class="game">
 | 
			
		||||
				<a @click="game">
 | 
			
		||||
					<fa icon="gamepad"/>
 | 
			
		||||
					<p>%i18n:@game%</p>
 | 
			
		||||
					<p>{{ $t('game') }}</p>
 | 
			
		||||
					<template v-if="hasGameInvitations"><fa icon="circle"/></template>
 | 
			
		||||
				</a>
 | 
			
		||||
			</li>
 | 
			
		||||
@@ -39,10 +39,12 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import MkMessagingWindow from './messaging-window.vue';
 | 
			
		||||
import MkGameWindow from './game-window.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/ui.header.nav.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			hasGameInvitations: false,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="notifications" v-hotkey.global="keymap">
 | 
			
		||||
	<button :data-active="isOpen" @click="toggle" title="%i18n:@title%">
 | 
			
		||||
	<button :data-active="isOpen" @click="toggle" :title="$t('title')">
 | 
			
		||||
		<i class="bell"><fa :icon="['far', 'bell']"/></i>
 | 
			
		||||
		<i class="circle" v-if="hasUnreadNotification"><fa icon="circle"/></i>
 | 
			
		||||
	</button>
 | 
			
		||||
@@ -12,9 +12,11 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import contains from '../../../common/scripts/contains';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/ui.header.notifications.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			isOpen: false
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,15 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="note">
 | 
			
		||||
	<button @click="post" title="%i18n:@post%"><fa icon="pencil-alt"/></button>
 | 
			
		||||
	<button @click="post" :title="$t('post')"><fa icon="pencil-alt"/></button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/ui.header.post.vue'),
 | 
			
		||||
	methods: {
 | 
			
		||||
		post() {
 | 
			
		||||
			(this as any).apis.post();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,15 +1,17 @@
 | 
			
		||||
<template>
 | 
			
		||||
<form class="search" @submit.prevent="onSubmit">
 | 
			
		||||
	<i><fa icon="search"/></i>
 | 
			
		||||
	<input v-model="q" type="search" placeholder="%i18n:@placeholder%"/>
 | 
			
		||||
	<input v-model="q" type="search" :placeholder="$t('placeholder')"/>
 | 
			
		||||
	<div class="result"></div>
 | 
			
		||||
</form>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/ui.header.search.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			q: ''
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="header" :style="style">
 | 
			
		||||
	<p class="warn" v-if="env != 'production'">%i18n:common.do-not-use-in-production%</p>
 | 
			
		||||
	<mk-special-message/>
 | 
			
		||||
	<p class="warn" v-if="env != 'production'">{{ $t('@.do-not-use-in-production') }}</p>
 | 
			
		||||
	<div class="main" ref="main">
 | 
			
		||||
		<div class="backdrop"></div>
 | 
			
		||||
		<div class="main">
 | 
			
		||||
@@ -29,6 +28,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import * as anime from 'animejs';
 | 
			
		||||
import { env } from '../../../config';
 | 
			
		||||
 | 
			
		||||
@@ -40,6 +40,7 @@ import XPost from './ui.header.post.vue';
 | 
			
		||||
import XClock from './ui.header.clock.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n(),
 | 
			
		||||
	components: {
 | 
			
		||||
		XNav,
 | 
			
		||||
		XSearch,
 | 
			
		||||
 
 | 
			
		||||
@@ -2,7 +2,7 @@
 | 
			
		||||
<div class="header" :class="navbar">
 | 
			
		||||
	<div class="body">
 | 
			
		||||
		<div class="post">
 | 
			
		||||
			<button @click="post" title="%i18n:@post%"><fa icon="pencil-alt"/></button>
 | 
			
		||||
			<button @click="post" :title="$t('title')"><fa icon="pencil-alt"/></button>
 | 
			
		||||
		</div>
 | 
			
		||||
 | 
			
		||||
		<div class="nav" v-if="$store.getters.isSignedIn">
 | 
			
		||||
@@ -77,6 +77,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import MkUserListsWindow from './user-lists-window.vue';
 | 
			
		||||
import MkFollowRequestsWindow from './received-follow-requests-window.vue';
 | 
			
		||||
import MkSettingsWindow from './settings-window.vue';
 | 
			
		||||
@@ -86,6 +87,7 @@ import MkGameWindow from './game-window.vue';
 | 
			
		||||
import contains from '../../../common/scripts/contains';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/ui.sidebar.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			hasGameInvitations: false,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
<template>
 | 
			
		||||
<mk-window ref="window" is-modal width="450px" height="500px" @closed="destroyDom">
 | 
			
		||||
	<span slot="header"><fa icon="list"/> %i18n:@title%</span>
 | 
			
		||||
	<span slot="header"><fa icon="list"/> {{ $t('title') }}</span>
 | 
			
		||||
 | 
			
		||||
	<div class="xkxvokkjlptzyewouewmceqcxhpgzprp">
 | 
			
		||||
		<button class="ui" @click="add">%i18n:@create-list%</button>
 | 
			
		||||
		<button class="ui" @click="add">{{ $t('create-list') }}</button>
 | 
			
		||||
		<a v-for="list in lists" :key="list.id" @click="choice(list)">{{ list.title }}</a>
 | 
			
		||||
	</div>
 | 
			
		||||
</mk-window>
 | 
			
		||||
@@ -11,7 +11,10 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/user-lists-window.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
@@ -27,7 +30,7 @@ export default Vue.extend({
 | 
			
		||||
	methods: {
 | 
			
		||||
		add() {
 | 
			
		||||
			(this as any).apis.input({
 | 
			
		||||
				title: '%i18n:@list-name%',
 | 
			
		||||
				title: this.$t('list-name'),
 | 
			
		||||
			}).then(async title => {
 | 
			
		||||
				const list = await (this as any).api('users/lists/create', {
 | 
			
		||||
					title
 | 
			
		||||
 
 | 
			
		||||
@@ -10,13 +10,13 @@
 | 
			
		||||
		<div class="description">{{ u.description }}</div>
 | 
			
		||||
		<div class="status">
 | 
			
		||||
			<div>
 | 
			
		||||
				<p>%i18n:@notes%</p><span>{{ u.notesCount }}</span>
 | 
			
		||||
				<p>{{ $t('notes') }}</p><span>{{ u.notesCount }}</span>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div>
 | 
			
		||||
				<p>%i18n:@following%</p><span>{{ u.followingCount }}</span>
 | 
			
		||||
				<p>{{ $t('following') }}</p><span>{{ u.followingCount }}</span>
 | 
			
		||||
			</div>
 | 
			
		||||
			<div>
 | 
			
		||||
				<p>%i18n:@followers%</p><span>{{ u.followersCount }}</span>
 | 
			
		||||
				<p>{{ $t('followers') }}</p><span>{{ u.followersCount }}</span>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<mk-follow-button v-if="$store.getters.isSignedIn && u.id != $store.state.i.id" :user="u"/>
 | 
			
		||||
@@ -26,10 +26,12 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import * as anime from 'animejs';
 | 
			
		||||
import parseAcct from '../../../../../misc/acct/parse';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/user-preview.vue'),
 | 
			
		||||
	props: {
 | 
			
		||||
		user: {
 | 
			
		||||
			type: [Object, String],
 | 
			
		||||
 
 | 
			
		||||
@@ -8,10 +8,10 @@
 | 
			
		||||
			>
 | 
			
		||||
				<h1><slot name="header"></slot></h1>
 | 
			
		||||
				<div>
 | 
			
		||||
					<button class="popout" v-if="popoutUrl" @mousedown.stop="() => {}" @click="popout" title="%i18n:@popout%">
 | 
			
		||||
					<button class="popout" v-if="popoutUrl" @mousedown.stop="() => {}" @click="popout" :title="$t('title')">
 | 
			
		||||
						<i><fa :icon="['far', 'window-restore']"/></i>
 | 
			
		||||
					</button>
 | 
			
		||||
					<button class="close" v-if="canClose" @mousedown.stop="() => {}" @click="close" title="%i18n:@close%">
 | 
			
		||||
					<button class="close" v-if="canClose" @mousedown.stop="() => {}" @click="close" :title="$t('title')">
 | 
			
		||||
						<i><fa icon="times"/></i>
 | 
			
		||||
					</button>
 | 
			
		||||
				</div>
 | 
			
		||||
@@ -36,6 +36,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import * as anime from 'animejs';
 | 
			
		||||
import contains from '../../../common/scripts/contains';
 | 
			
		||||
 | 
			
		||||
@@ -55,6 +56,7 @@ function dragClear(fn) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/components/window.vue'),
 | 
			
		||||
	props: {
 | 
			
		||||
		isModal: {
 | 
			
		||||
			type: Boolean,
 | 
			
		||||
 
 | 
			
		||||
@@ -27,11 +27,13 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
import Menu from '../../../../common/views/components/menu.vue';
 | 
			
		||||
import contextmenu from '../../../api/contextmenu';
 | 
			
		||||
import { countIf } from '../../../../../../prelude/array';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('deck'),
 | 
			
		||||
	props: {
 | 
			
		||||
		column: {
 | 
			
		||||
			type: Object,
 | 
			
		||||
@@ -164,10 +166,10 @@ export default Vue.extend({
 | 
			
		||||
		getMenu() {
 | 
			
		||||
			const items = [{
 | 
			
		||||
				icon: 'pencil-alt',
 | 
			
		||||
				text: '%i18n:common.deck.rename%',
 | 
			
		||||
				text: this.$t('rename'),
 | 
			
		||||
				action: () => {
 | 
			
		||||
					(this as any).apis.input({
 | 
			
		||||
						title: '%i18n:common.deck.rename%',
 | 
			
		||||
						title: this.$t('rename'),
 | 
			
		||||
						default: this.name,
 | 
			
		||||
						allowEmpty: false
 | 
			
		||||
					}).then(name => {
 | 
			
		||||
@@ -176,43 +178,43 @@ export default Vue.extend({
 | 
			
		||||
				}
 | 
			
		||||
			}, null, {
 | 
			
		||||
				icon: 'arrow-left',
 | 
			
		||||
				text: '%i18n:common.deck.swap-left%',
 | 
			
		||||
				text: this.$t('swap-left'),
 | 
			
		||||
				action: () => {
 | 
			
		||||
					this.$store.dispatch('settings/swapLeftDeckColumn', this.column.id);
 | 
			
		||||
				}
 | 
			
		||||
			}, {
 | 
			
		||||
				icon: 'arrow-right',
 | 
			
		||||
				text: '%i18n:common.deck.swap-right%',
 | 
			
		||||
				text: this.$t('swap-right'),
 | 
			
		||||
				action: () => {
 | 
			
		||||
					this.$store.dispatch('settings/swapRightDeckColumn', this.column.id);
 | 
			
		||||
				}
 | 
			
		||||
			}, this.isStacked ? {
 | 
			
		||||
				icon: 'arrow-up',
 | 
			
		||||
				text: '%i18n:common.deck.swap-up%',
 | 
			
		||||
				text: this.$t('swap-up'),
 | 
			
		||||
				action: () => {
 | 
			
		||||
					this.$store.dispatch('settings/swapUpDeckColumn', this.column.id);
 | 
			
		||||
				}
 | 
			
		||||
			} : undefined, this.isStacked ? {
 | 
			
		||||
				icon: 'arrow-down',
 | 
			
		||||
				text: '%i18n:common.deck.swap-down%',
 | 
			
		||||
				text: this.$t('swap-down'),
 | 
			
		||||
				action: () => {
 | 
			
		||||
					this.$store.dispatch('settings/swapDownDeckColumn', this.column.id);
 | 
			
		||||
				}
 | 
			
		||||
			} : undefined, null, {
 | 
			
		||||
				icon: ['far', 'window-restore'],
 | 
			
		||||
				text: '%i18n:common.deck.stack-left%',
 | 
			
		||||
				text: this.$t('stack-left'),
 | 
			
		||||
				action: () => {
 | 
			
		||||
					this.$store.dispatch('settings/stackLeftDeckColumn', this.column.id);
 | 
			
		||||
				}
 | 
			
		||||
			}, this.isStacked ? {
 | 
			
		||||
				icon: ['far', 'window-maximize'],
 | 
			
		||||
				text: '%i18n:common.deck.pop-right%',
 | 
			
		||||
				text: this.$t('pop-right'),
 | 
			
		||||
				action: () => {
 | 
			
		||||
					this.$store.dispatch('settings/popRightDeckColumn', this.column.id);
 | 
			
		||||
				}
 | 
			
		||||
			} : undefined, null, {
 | 
			
		||||
				icon: ['far', 'trash-alt'],
 | 
			
		||||
				text: '%i18n:common.deck.remove%',
 | 
			
		||||
				text: this.$t('remove'),
 | 
			
		||||
				action: () => {
 | 
			
		||||
					this.$store.dispatch('settings/removeDeckColumn', this.column.id);
 | 
			
		||||
				}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,10 +8,12 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
import XColumn from './deck.column.vue';
 | 
			
		||||
import XDirect from './deck.direct.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n(),
 | 
			
		||||
	components: {
 | 
			
		||||
		XColumn,
 | 
			
		||||
		XDirect
 | 
			
		||||
@@ -31,7 +33,7 @@ export default Vue.extend({
 | 
			
		||||
	computed: {
 | 
			
		||||
		name(): string {
 | 
			
		||||
			if (this.column.name) return this.column.name;
 | 
			
		||||
			return '%i18n:common.deck.direct%';
 | 
			
		||||
			return this.$t('@deck.direct');
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<template>
 | 
			
		||||
	<x-notes ref="timeline" :more="existMore ? more : null"/>
 | 
			
		||||
<x-notes ref="timeline" :more="existMore ? more : null"/>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
 
 | 
			
		||||
@@ -8,10 +8,12 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
import XColumn from './deck.column.vue';
 | 
			
		||||
import XMentions from './deck.mentions.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n(),
 | 
			
		||||
	components: {
 | 
			
		||||
		XColumn,
 | 
			
		||||
		XMentions
 | 
			
		||||
@@ -31,7 +33,7 @@ export default Vue.extend({
 | 
			
		||||
	computed: {
 | 
			
		||||
		name(): string {
 | 
			
		||||
			if (this.column.name) return this.column.name;
 | 
			
		||||
			return '%i18n:common.deck.mentions%';
 | 
			
		||||
			return this.$t('@deck.mentions');
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
<template>
 | 
			
		||||
	<x-notes ref="timeline" :more="existMore ? more : null"/>
 | 
			
		||||
<x-notes ref="timeline" :more="existMore ? more : null"/>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,8 @@
 | 
			
		||||
	<div class="rvtscbadixhhbsczoorqoaygovdeecsx" v-if="note">
 | 
			
		||||
		<div class="is-remote" v-if="note.user.host != null">
 | 
			
		||||
			<details>
 | 
			
		||||
				<summary><fa icon="exclamation-triangle"/> %i18n:common.is-remote-post%</summary>
 | 
			
		||||
				<a :href="note.url || note.uri" target="_blank">%i18n:common.view-on-remote%</a>
 | 
			
		||||
				<summary><fa icon="exclamation-triangle"/> {{ $t('@.is-remote-post') }}</summary>
 | 
			
		||||
				<a :href="note.url || note.uri" target="_blank">{{ $t('@.view-on-remote') }}</a>
 | 
			
		||||
			</details>
 | 
			
		||||
		</div>
 | 
			
		||||
		<x-note :note="note" :detail="true" :mini="true"/>
 | 
			
		||||
@@ -18,11 +18,13 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
import XColumn from './deck.column.vue';
 | 
			
		||||
import XNotes from './deck.notes.vue';
 | 
			
		||||
import XNote from '../../components/note.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n(),
 | 
			
		||||
	components: {
 | 
			
		||||
		XColumn,
 | 
			
		||||
		XNotes,
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@
 | 
			
		||||
 | 
			
		||||
	<footer v-if="more">
 | 
			
		||||
		<button @click="loadMore" :disabled="moreFetching" :style="{ cursor: moreFetching ? 'wait' : 'pointer' }">
 | 
			
		||||
			<template v-if="!moreFetching">%i18n:@load-more%</template>
 | 
			
		||||
			<template v-if="!moreFetching">{{ $t('@.load-more') }}</template>
 | 
			
		||||
			<template v-if="moreFetching"><fa icon="spinner .pulse" fixed-width/></template>
 | 
			
		||||
		</button>
 | 
			
		||||
	</footer>
 | 
			
		||||
@@ -39,12 +39,14 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
 | 
			
		||||
import XNote from '../../components/note.vue';
 | 
			
		||||
 | 
			
		||||
const displayLimit = 20;
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n(),
 | 
			
		||||
	components: {
 | 
			
		||||
		XNote
 | 
			
		||||
	},
 | 
			
		||||
@@ -80,7 +82,7 @@ export default Vue.extend({
 | 
			
		||||
				const date = new Date(note.createdAt).getDate();
 | 
			
		||||
				const month = new Date(note.createdAt).getMonth() + 1;
 | 
			
		||||
				note._date = date;
 | 
			
		||||
				note._datetext = '%i18n:common.month-and-day%'.replace('{month}', month.toString()).replace('{day}', date.toString());
 | 
			
		||||
				note._datetext = this.$t('@.month-and-day').replace('{month}', month.toString()).replace('{day}', date.toString());
 | 
			
		||||
				return note;
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -8,10 +8,12 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
import XColumn from './deck.column.vue';
 | 
			
		||||
import XNotifications from './deck.notifications.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n(),
 | 
			
		||||
	components: {
 | 
			
		||||
		XColumn,
 | 
			
		||||
		XNotifications
 | 
			
		||||
@@ -31,7 +33,7 @@ export default Vue.extend({
 | 
			
		||||
	computed: {
 | 
			
		||||
		name(): string {
 | 
			
		||||
			if (this.column.name) return this.column.name;
 | 
			
		||||
			return '%i18n:common.deck.notifications%';
 | 
			
		||||
			return this.$t('@deck.notifications');
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
});
 | 
			
		||||
 
 | 
			
		||||
@@ -17,19 +17,21 @@
 | 
			
		||||
		</template>
 | 
			
		||||
	</component>
 | 
			
		||||
	<button class="more" :class="{ fetching: fetchingMoreNotifications }" v-if="moreNotifications" @click="fetchMoreNotifications" :disabled="fetchingMoreNotifications">
 | 
			
		||||
		<template v-if="fetchingMoreNotifications"><fa icon="spinner .pulse" fixed-width/></template>{{ fetchingMoreNotifications ? '%i18n:common.loading%' : '%i18n:@more%' }}
 | 
			
		||||
		<template v-if="fetchingMoreNotifications"><fa icon="spinner .pulse" fixed-width/></template>{{ fetchingMoreNotifications ? this.$t('@.loading') : this.$t('@.load-more') }}
 | 
			
		||||
	</button>
 | 
			
		||||
	<p class="empty" v-if="notifications.length == 0 && !fetching">%i18n:@empty%</p>
 | 
			
		||||
	<p class="empty" v-if="notifications.length == 0 && !fetching">{{ $t('empty') }}</p>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
import XNotification from './deck.notification.vue';
 | 
			
		||||
 | 
			
		||||
const displayLimit = 20;
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n(),
 | 
			
		||||
	components: {
 | 
			
		||||
		XNotification
 | 
			
		||||
	},
 | 
			
		||||
@@ -53,7 +55,7 @@ export default Vue.extend({
 | 
			
		||||
				const date = new Date(notification.createdAt).getDate();
 | 
			
		||||
				const month = new Date(notification.createdAt).getMonth() + 1;
 | 
			
		||||
				notification._date = date;
 | 
			
		||||
				notification._datetext = '%i18n:common.month-and-day%'.replace('{month}', month.toString()).replace('{day}', date.toString());
 | 
			
		||||
				notification._datetext = this.$t('@.month-and-day').replace('{month}', month.toString()).replace('{day}', date.toString());
 | 
			
		||||
				return notification;
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -11,8 +11,8 @@
 | 
			
		||||
	</span>
 | 
			
		||||
 | 
			
		||||
	<div class="editor" style="padding:0 12px" v-if="edit">
 | 
			
		||||
		<ui-switch v-model="column.isMediaOnly" @change="onChangeSettings">%i18n:@is-media-only%</ui-switch>
 | 
			
		||||
		<ui-switch v-model="column.isMediaView" @change="onChangeSettings">%i18n:@is-media-view%</ui-switch>
 | 
			
		||||
		<ui-switch v-model="column.isMediaOnly" @change="onChangeSettings">{{ $t('is-media-only') }}</ui-switch>
 | 
			
		||||
		<ui-switch v-model="column.isMediaView" @change="onChangeSettings">{{ $t('is-media-view') }}</ui-switch>
 | 
			
		||||
	</div>
 | 
			
		||||
 | 
			
		||||
	<x-list-tl v-if="column.type == 'list'"
 | 
			
		||||
@@ -38,12 +38,14 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
import XColumn from './deck.column.vue';
 | 
			
		||||
import XTl from './deck.tl.vue';
 | 
			
		||||
import XListTl from './deck.list-tl.vue';
 | 
			
		||||
import XHashtagTl from './deck.hashtag-tl.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('deck/deck.tl-column.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		XColumn,
 | 
			
		||||
		XTl,
 | 
			
		||||
@@ -67,7 +69,7 @@ export default Vue.extend({
 | 
			
		||||
			edit: false,
 | 
			
		||||
			menu: [{
 | 
			
		||||
				icon: 'cog',
 | 
			
		||||
				text: '%i18n:@edit%',
 | 
			
		||||
				text: this.$t('edit'),
 | 
			
		||||
				action: () => {
 | 
			
		||||
					this.edit = !this.edit;
 | 
			
		||||
				}
 | 
			
		||||
@@ -80,10 +82,10 @@ export default Vue.extend({
 | 
			
		||||
			if (this.column.name) return this.column.name;
 | 
			
		||||
 | 
			
		||||
			switch (this.column.type) {
 | 
			
		||||
				case 'home': return '%i18n:common.deck.home%';
 | 
			
		||||
				case 'local': return '%i18n:common.deck.local%';
 | 
			
		||||
				case 'hybrid': return '%i18n:common.deck.hybrid%';
 | 
			
		||||
				case 'global': return '%i18n:common.deck.global%';
 | 
			
		||||
				case 'home': return this.$t('@deck.home');
 | 
			
		||||
				case 'local': return this.$t('@deck.local');
 | 
			
		||||
				case 'hybrid': return this.$t('@deck.hybrid');
 | 
			
		||||
				case 'global': return this.$t('@deck.global');
 | 
			
		||||
				case 'list': return this.column.list.title;
 | 
			
		||||
				case 'hashtag': return this.$store.state.settings.tagTimelines.find(x => x.id == this.column.tagTlId).title;
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,8 +7,8 @@
 | 
			
		||||
	<div class="zubukjlciycdsyynicqrnlsmdwmymzqu" v-if="user">
 | 
			
		||||
		<div class="is-remote" v-if="user.host != null">
 | 
			
		||||
			<details>
 | 
			
		||||
				<summary><fa icon="exclamation-triangle"/> %i18n:common.is-remote-user%</summary>
 | 
			
		||||
				<a :href="user.url || user.uri" target="_blank">%i18n:common.view-on-remote%</a>
 | 
			
		||||
				<summary><fa icon="exclamation-triangle"/> {{ $t('@.is-remote-user') }}</summary>
 | 
			
		||||
				<a :href="user.url || user.uri" target="_blank">{{ $t('@.view-on-remote') }}</a>
 | 
			
		||||
			</details>
 | 
			
		||||
		</div>
 | 
			
		||||
		<header :style="bannerStyle">
 | 
			
		||||
@@ -27,20 +27,20 @@
 | 
			
		||||
			<div class="counts">
 | 
			
		||||
				<div>
 | 
			
		||||
					<b>{{ user.notesCount | number }}</b>
 | 
			
		||||
					<span>%i18n:@posts%</span>
 | 
			
		||||
					<span>{{ $t('posts') }}</span>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div>
 | 
			
		||||
					<b>{{ user.followingCount | number }}</b>
 | 
			
		||||
					<span>%i18n:@following%</span>
 | 
			
		||||
					<span>{{ $t('following') }}</span>
 | 
			
		||||
				</div>
 | 
			
		||||
				<div>
 | 
			
		||||
					<b>{{ user.followersCount | number }}</b>
 | 
			
		||||
					<span>%i18n:@followers%</span>
 | 
			
		||||
					<span>{{ $t('followers') }}</span>
 | 
			
		||||
				</div>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="pinned" v-if="user.pinnedNotes && user.pinnedNotes.length > 0">
 | 
			
		||||
			<p class="caption" @click="toggleShowPinned"><fa icon="thumbtack"/> %i18n:@pinned-notes%</p>
 | 
			
		||||
			<p class="caption" @click="toggleShowPinned"><fa icon="thumbtack"/> {{ $t('pinned-notes') }}</p>
 | 
			
		||||
			<span class="angle" v-if="showPinned"><fa icon="angle-up"/></span>
 | 
			
		||||
			<span class="angle" v-else><fa icon="angle-down"/></span>
 | 
			
		||||
			<div class="notes" v-show="showPinned">
 | 
			
		||||
@@ -48,7 +48,7 @@
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="images" v-if="images.length > 0">
 | 
			
		||||
			<p class="caption" @click="toggleShowImages"><fa :icon="['far', 'images']"/> %i18n:@images%</p>
 | 
			
		||||
			<p class="caption" @click="toggleShowImages"><fa :icon="['far', 'images']"/> {{ $t('images') }}</p>
 | 
			
		||||
			<span class="angle" v-if="showImages"><fa icon="angle-up"/></span>
 | 
			
		||||
			<span class="angle" v-else><fa icon="angle-down"/></span>
 | 
			
		||||
			<div v-show="showImages">
 | 
			
		||||
@@ -61,7 +61,7 @@
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="activity">
 | 
			
		||||
			<p class="caption" @click="toggleShowActivity"><fa :icon="['far', 'chart-bar']"/> %i18n:@activity%</p>
 | 
			
		||||
			<p class="caption" @click="toggleShowActivity"><fa :icon="['far', 'chart-bar']"/> {{ $t('activity') }}</p>
 | 
			
		||||
			<span class="angle" v-if="showActivity"><fa icon="angle-up"/></span>
 | 
			
		||||
			<span class="angle" v-else><fa icon="angle-down"/></span>
 | 
			
		||||
			<div v-show="showActivity">
 | 
			
		||||
@@ -69,7 +69,7 @@
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="tl">
 | 
			
		||||
			<p class="caption"><fa :icon="['far', 'comment-alt']"/> %i18n:@timeline%</p>
 | 
			
		||||
			<p class="caption"><fa :icon="['far', 'comment-alt']"/> {{ $t('timeline') }}</p>
 | 
			
		||||
			<div>
 | 
			
		||||
				<x-notes ref="timeline" :more="existMore ? fetchMoreNotes : null"/>
 | 
			
		||||
			</div>
 | 
			
		||||
@@ -80,6 +80,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
import parseAcct from '../../../../../../misc/acct/parse';
 | 
			
		||||
import XColumn from './deck.column.vue';
 | 
			
		||||
import XNotes from './deck.notes.vue';
 | 
			
		||||
@@ -93,6 +94,7 @@ import * as ApexCharts from 'apexcharts';
 | 
			
		||||
const fetchLimit = 10;
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('deck/deck.user-column.vue'),
 | 
			
		||||
	components: {
 | 
			
		||||
		XColumn,
 | 
			
		||||
		XNotes,
 | 
			
		||||
@@ -295,7 +297,7 @@ export default Vue.extend({
 | 
			
		||||
		menu() {
 | 
			
		||||
			let menu = [{
 | 
			
		||||
				icon: 'list',
 | 
			
		||||
				text: '%i18n:@push-to-a-list%',
 | 
			
		||||
				text: this.$t('push-to-a-list'),
 | 
			
		||||
				action: () => {
 | 
			
		||||
					const w = (this as any).os.new(MkUserListsWindow);
 | 
			
		||||
					w.$once('choosen', async list => {
 | 
			
		||||
 
 | 
			
		||||
@@ -14,13 +14,14 @@
 | 
			
		||||
			<x-note-column v-else-if="temporaryColumn.type == 'note'" :note-id="temporaryColumn.noteId" :key="temporaryColumn.noteId"/>
 | 
			
		||||
			<x-hashtag-column v-else-if="temporaryColumn.type == 'tag'" :tag="temporaryColumn.tag" :key="temporaryColumn.tag"/>
 | 
			
		||||
		</template>
 | 
			
		||||
		<button ref="add" @click="add" title="%i18n:common.deck.add-column%"><fa icon="plus"/></button>
 | 
			
		||||
		<button ref="add" @click="add" :title="$t('@deck.add-column')"><fa icon="plus"/></button>
 | 
			
		||||
	</div>
 | 
			
		||||
</mk-ui>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
import XColumnCore from './deck.column-core.vue';
 | 
			
		||||
import Menu from '../../../../common/views/components/menu.vue';
 | 
			
		||||
import MkUserListsWindow from '../../components/user-lists-window.vue';
 | 
			
		||||
@@ -31,6 +32,7 @@ import XHashtagColumn from './deck.hashtag-column.vue';
 | 
			
		||||
import * as uuid from 'uuid';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('deck'),
 | 
			
		||||
	components: {
 | 
			
		||||
		XColumnCore,
 | 
			
		||||
		XUserColumn,
 | 
			
		||||
@@ -183,7 +185,7 @@ export default Vue.extend({
 | 
			
		||||
				compact: true,
 | 
			
		||||
				items: [{
 | 
			
		||||
					icon: 'home',
 | 
			
		||||
					text: '%i18n:common.deck.home%',
 | 
			
		||||
					text: this.$t('@deck.home'),
 | 
			
		||||
					action: () => {
 | 
			
		||||
						this.$store.dispatch('settings/addDeckColumn', {
 | 
			
		||||
							id: uuid(),
 | 
			
		||||
@@ -192,7 +194,7 @@ export default Vue.extend({
 | 
			
		||||
					}
 | 
			
		||||
				}, {
 | 
			
		||||
					icon: ['far', 'comments'],
 | 
			
		||||
					text: '%i18n:common.deck.local%',
 | 
			
		||||
					text: this.$t('@deck.local'),
 | 
			
		||||
					action: () => {
 | 
			
		||||
						this.$store.dispatch('settings/addDeckColumn', {
 | 
			
		||||
							id: uuid(),
 | 
			
		||||
@@ -201,7 +203,7 @@ export default Vue.extend({
 | 
			
		||||
					}
 | 
			
		||||
				}, {
 | 
			
		||||
					icon: 'share-alt',
 | 
			
		||||
					text: '%i18n:common.deck.hybrid%',
 | 
			
		||||
					text: this.$t('@deck.hybrid'),
 | 
			
		||||
					action: () => {
 | 
			
		||||
						this.$store.dispatch('settings/addDeckColumn', {
 | 
			
		||||
							id: uuid(),
 | 
			
		||||
@@ -210,7 +212,7 @@ export default Vue.extend({
 | 
			
		||||
					}
 | 
			
		||||
				}, {
 | 
			
		||||
					icon: 'globe',
 | 
			
		||||
					text: '%i18n:common.deck.global%',
 | 
			
		||||
					text: this.$t('@deck.global'),
 | 
			
		||||
					action: () => {
 | 
			
		||||
						this.$store.dispatch('settings/addDeckColumn', {
 | 
			
		||||
							id: uuid(),
 | 
			
		||||
@@ -219,7 +221,7 @@ export default Vue.extend({
 | 
			
		||||
					}
 | 
			
		||||
				}, {
 | 
			
		||||
					icon: 'at',
 | 
			
		||||
					text: '%i18n:common.deck.mentions%',
 | 
			
		||||
					text: this.$t('@deck.mentions'),
 | 
			
		||||
					action: () => {
 | 
			
		||||
						this.$store.dispatch('settings/addDeckColumn', {
 | 
			
		||||
							id: uuid(),
 | 
			
		||||
@@ -228,7 +230,7 @@ export default Vue.extend({
 | 
			
		||||
					}
 | 
			
		||||
				}, {
 | 
			
		||||
					icon: ['far', 'envelope'],
 | 
			
		||||
					text: '%i18n:common.deck.direct%',
 | 
			
		||||
					text: this.$t('@deck.direct'),
 | 
			
		||||
					action: () => {
 | 
			
		||||
						this.$store.dispatch('settings/addDeckColumn', {
 | 
			
		||||
							id: uuid(),
 | 
			
		||||
@@ -237,7 +239,7 @@ export default Vue.extend({
 | 
			
		||||
					}
 | 
			
		||||
				}, {
 | 
			
		||||
					icon: 'list',
 | 
			
		||||
					text: '%i18n:common.deck.list%',
 | 
			
		||||
					text: this.$t('@deck.list'),
 | 
			
		||||
					action: () => {
 | 
			
		||||
						const w = (this as any).os.new(MkUserListsWindow);
 | 
			
		||||
						w.$once('choosen', list => {
 | 
			
		||||
@@ -251,10 +253,10 @@ export default Vue.extend({
 | 
			
		||||
					}
 | 
			
		||||
				}, {
 | 
			
		||||
					icon: 'hashtag',
 | 
			
		||||
					text: '%i18n:common.deck.hashtag%',
 | 
			
		||||
					text: this.$t('@deck.hashtag'),
 | 
			
		||||
					action: () => {
 | 
			
		||||
						(this as any).apis.input({
 | 
			
		||||
							title: '%i18n:@enter-hashtag-tl-title%'
 | 
			
		||||
							title: this.$t('enter-hashtag-tl-title')
 | 
			
		||||
						}).then(title => {
 | 
			
		||||
							this.$store.dispatch('settings/addDeckColumn', {
 | 
			
		||||
								id: uuid(),
 | 
			
		||||
@@ -265,7 +267,7 @@ export default Vue.extend({
 | 
			
		||||
					}
 | 
			
		||||
				}, {
 | 
			
		||||
					icon: ['far', 'bell'],
 | 
			
		||||
					text: '%i18n:common.deck.notifications%',
 | 
			
		||||
					text: this.$t('@deck.notifications'),
 | 
			
		||||
					action: () => {
 | 
			
		||||
						this.$store.dispatch('settings/addDeckColumn', {
 | 
			
		||||
							id: uuid(),
 | 
			
		||||
@@ -274,7 +276,7 @@ export default Vue.extend({
 | 
			
		||||
					}
 | 
			
		||||
				}, {
 | 
			
		||||
					icon: 'calculator',
 | 
			
		||||
					text: '%i18n:common.deck.widgets%',
 | 
			
		||||
					text: this.$t('@deck.widgets'),
 | 
			
		||||
					action: () => {
 | 
			
		||||
						this.$store.dispatch('settings/addDeckColumn', {
 | 
			
		||||
							id: uuid(),
 | 
			
		||||
 
 | 
			
		||||
@@ -6,29 +6,29 @@
 | 
			
		||||
		<template v-if="edit">
 | 
			
		||||
			<header>
 | 
			
		||||
				<select v-model="widgetAdderSelected" @change="addWidget">
 | 
			
		||||
					<option value="profile">%i18n:common.widgets.profile%</option>
 | 
			
		||||
					<option value="analog-clock">%i18n:common.widgets.analog-clock%</option>
 | 
			
		||||
					<option value="calendar">%i18n:common.widgets.calendar%</option>
 | 
			
		||||
					<option value="timemachine">%i18n:common.widgets.timemachine%</option>
 | 
			
		||||
					<option value="activity">%i18n:common.widgets.activity%</option>
 | 
			
		||||
					<option value="rss">%i18n:common.widgets.rss%</option>
 | 
			
		||||
					<option value="trends">%i18n:common.widgets.trends%</option>
 | 
			
		||||
					<option value="photo-stream">%i18n:common.widgets.photo-stream%</option>
 | 
			
		||||
					<option value="slideshow">%i18n:common.widgets.slideshow%</option>
 | 
			
		||||
					<option value="version">%i18n:common.widgets.version%</option>
 | 
			
		||||
					<option value="broadcast">%i18n:common.widgets.broadcast%</option>
 | 
			
		||||
					<option value="notifications">%i18n:common.widgets.notifications%</option>
 | 
			
		||||
					<option value="users">%i18n:common.widgets.users%</option>
 | 
			
		||||
					<option value="polls">%i18n:common.widgets.polls%</option>
 | 
			
		||||
					<option value="post-form">%i18n:common.widgets.post-form%</option>
 | 
			
		||||
					<option value="messaging">%i18n:common.widgets.messaging%</option>
 | 
			
		||||
					<option value="memo">%i18n:common.widgets.memo%</option>
 | 
			
		||||
					<option value="hashtags">%i18n:common.widgets.hashtags%</option>
 | 
			
		||||
					<option value="posts-monitor">%i18n:common.widgets.posts-monitor%</option>
 | 
			
		||||
					<option value="server">%i18n:common.widgets.server%</option>
 | 
			
		||||
					<option value="donation">%i18n:common.widgets.donation%</option>
 | 
			
		||||
					<option value="nav">%i18n:common.widgets.nav%</option>
 | 
			
		||||
					<option value="tips">%i18n:common.widgets.tips%</option>
 | 
			
		||||
					<option value="profile">{{ $t('@.widgets.profile') }}</option>
 | 
			
		||||
					<option value="analog-clock">{{ $t('@.widgets.analog-clock') }}</option>
 | 
			
		||||
					<option value="calendar">{{ $t('@.widgets.calendar') }}</option>
 | 
			
		||||
					<option value="timemachine">{{ $t('@.widgets.timemachine') }}</option>
 | 
			
		||||
					<option value="activity">{{ $t('@.widgets.activity') }}</option>
 | 
			
		||||
					<option value="rss">{{ $t('@.widgets.rss') }}</option>
 | 
			
		||||
					<option value="trends">{{ $t('@.widgets.trends') }}</option>
 | 
			
		||||
					<option value="photo-stream">{{ $t('@.widgets.photo-stream') }}</option>
 | 
			
		||||
					<option value="slideshow">{{ $t('@.widgets.slideshow') }}</option>
 | 
			
		||||
					<option value="version">{{ $t('@.widgets.version') }}</option>
 | 
			
		||||
					<option value="broadcast">{{ $t('@.widgets.broadcast') }}</option>
 | 
			
		||||
					<option value="notifications">{{ $t('@.widgets.notifications') }}</option>
 | 
			
		||||
					<option value="users">{{ $t('@.widgets.users') }}</option>
 | 
			
		||||
					<option value="polls">{{ $t('@.widgets.polls') }}</option>
 | 
			
		||||
					<option value="post-form">{{ $t('@.widgets.post-form') }}</option>
 | 
			
		||||
					<option value="messaging">{{ $t('@.widgets.messaging') }}</option>
 | 
			
		||||
					<option value="memo">{{ $t('@.widgets.memo') }}</option>
 | 
			
		||||
					<option value="hashtags">{{ $t('@.widgets.hashtags') }}</option>
 | 
			
		||||
					<option value="posts-monitor">{{ $t('@.widgets.posts-monitor') }}</option>
 | 
			
		||||
					<option value="server">{{ $t('@.widgets.server') }}</option>
 | 
			
		||||
					<option value="donation">{{ $t('@.widgets.donation') }}</option>
 | 
			
		||||
					<option value="nav">{{ $t('@.widgets.nav') }}</option>
 | 
			
		||||
					<option value="tips">{{ $t('@.widgets.tips') }}</option>
 | 
			
		||||
				</select>
 | 
			
		||||
			</header>
 | 
			
		||||
			<x-draggable
 | 
			
		||||
@@ -51,11 +51,13 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
import XColumn from './deck.column.vue';
 | 
			
		||||
import * as XDraggable from 'vuedraggable';
 | 
			
		||||
import * as uuid from 'uuid';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n(),
 | 
			
		||||
	components: {
 | 
			
		||||
		XColumn,
 | 
			
		||||
		XDraggable
 | 
			
		||||
@@ -83,14 +85,14 @@ export default Vue.extend({
 | 
			
		||||
	computed: {
 | 
			
		||||
		name(): string {
 | 
			
		||||
			if (this.column.name) return this.column.name;
 | 
			
		||||
			return '%i18n:common.deck.widgets%';
 | 
			
		||||
			return this.$t('@deck.widgets');
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
 | 
			
		||||
	created() {
 | 
			
		||||
		this.menu = [{
 | 
			
		||||
			icon: 'cog',
 | 
			
		||||
			text: '%i18n:@edit%',
 | 
			
		||||
			text: this.$t('edit'),
 | 
			
		||||
			action: () => {
 | 
			
		||||
				this.edit = !this.edit;
 | 
			
		||||
			}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,7 +6,10 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/pages/drive.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			folder: null
 | 
			
		||||
@@ -16,11 +19,11 @@ export default Vue.extend({
 | 
			
		||||
		this.folder = this.$route.params.folder;
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		document.title = '%i18n:@title%';
 | 
			
		||||
		document.title = this.$t('title');
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		onMoveRoot() {
 | 
			
		||||
			const title = '%i18n:@title%';
 | 
			
		||||
			const title = this.$t('title');
 | 
			
		||||
 | 
			
		||||
			// Rewrite URL
 | 
			
		||||
			history.pushState(null, title, '/i/drive');
 | 
			
		||||
 
 | 
			
		||||
@@ -4,16 +4,18 @@
 | 
			
		||||
		<template v-for="favorite in favorites">
 | 
			
		||||
			<mk-note-detail class="post" :note="favorite.note" :key="favorite.note.id"/>
 | 
			
		||||
		</template>
 | 
			
		||||
		<a v-if="existMore" @click="more">%i18n:@more%</a>
 | 
			
		||||
		<a v-if="existMore" @click="more">{{ $t('@.load-more') }}</a>
 | 
			
		||||
	</main>
 | 
			
		||||
</mk-ui>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import Progress from '../../../common/scripts/loading';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,13 +1,3 @@
 | 
			
		||||
<template>
 | 
			
		||||
<mk-home customize/>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	mounted() {
 | 
			
		||||
		document.title = `${(this as any).os.instanceName} - %i18n:@title%`;
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
</script>
 | 
			
		||||
 
 | 
			
		||||
@@ -6,11 +6,13 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import Progress from '../../../common/scripts/loading';
 | 
			
		||||
import parseAcct from '../../../../../misc/acct/parse';
 | 
			
		||||
import getUserName from '../../../../../misc/get-user-name';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,8 @@
 | 
			
		||||
	<main v-if="!fetching">
 | 
			
		||||
		<mk-note-detail :note="note"/>
 | 
			
		||||
		<footer>
 | 
			
		||||
			<router-link v-if="note.next" :to="note.next"><fa icon="angle-left"/> %i18n:@next%</router-link>
 | 
			
		||||
			<router-link v-if="note.prev" :to="note.prev">%i18n:@prev% <fa icon="angle-right"/></router-link>
 | 
			
		||||
			<router-link v-if="note.next" :to="note.next"><fa icon="angle-left"/> {{ $t('next') }}</router-link>
 | 
			
		||||
			<router-link v-if="note.prev" :to="note.prev">{{ $t('prev') }} <fa icon="angle-right"/></router-link>
 | 
			
		||||
		</footer>
 | 
			
		||||
	</main>
 | 
			
		||||
</mk-ui>
 | 
			
		||||
@@ -12,9 +12,11 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import Progress from '../../../common/scripts/loading';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/pages/note.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
 
 | 
			
		||||
@@ -3,19 +3,21 @@
 | 
			
		||||
	<header :class="$style.header">
 | 
			
		||||
		<h1>{{ q }}</h1>
 | 
			
		||||
	</header>
 | 
			
		||||
	<p :class="$style.notAvailable" v-if="!fetching && notAvailable">%i18n:@not-available%</p>
 | 
			
		||||
	<p :class="$style.empty" v-if="!fetching && empty"><fa icon="search"/> {{ '%i18n:not-found%'.split('{}')[0] }}{{ q }}{{ '%i18n:not-found%'.split('{}')[1] }}</p>
 | 
			
		||||
	<p :class="$style.notAvailable" v-if="!fetching && notAvailable">{{ $t('not-available') }}</p>
 | 
			
		||||
	<p :class="$style.empty" v-if="!fetching && empty"><fa icon="search"/> {{ $t('not-found', { q }) }}</p>
 | 
			
		||||
	<mk-notes ref="timeline" :class="$style.notes" :more="existMore ? more : null"/>
 | 
			
		||||
</mk-ui>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import Progress from '../../../common/scripts/loading';
 | 
			
		||||
 | 
			
		||||
const limit = 20;
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/pages/search.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
 
 | 
			
		||||
@@ -6,17 +6,19 @@
 | 
			
		||||
		@change-selection="onChangeSelection"
 | 
			
		||||
	/>
 | 
			
		||||
	<footer>
 | 
			
		||||
		<button class="upload" title="%i18n:@upload%" @click="upload"><fa icon="upload"/></button>
 | 
			
		||||
		<button class="cancel" @click="close">%i18n:@cancel%</button>
 | 
			
		||||
		<button class="ok" @click="ok">%i18n:@ok%</button>
 | 
			
		||||
		<button class="upload" :title="$t('upload')" @click="upload"><fa icon="upload"/></button>
 | 
			
		||||
		<button class="cancel" @click="close">{{ $t('cancel') }}</button>
 | 
			
		||||
		<button class="ok" @click="ok">{{ $t('ok') }}</button>
 | 
			
		||||
	</footer>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/pages/selectdrive.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			files: []
 | 
			
		||||
@@ -29,7 +31,7 @@ export default Vue.extend({
 | 
			
		||||
		}
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
		document.title = '%i18n:@title%';
 | 
			
		||||
		document.title = this.$t('title');
 | 
			
		||||
	},
 | 
			
		||||
	methods: {
 | 
			
		||||
		onSelected(file) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,21 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="pptjhabgjtt7kwskbfv4y3uml6fpuhmr">
 | 
			
		||||
	<h1>{{ '%i18n:@share-with%'.replace('{}', name) }}</h1>
 | 
			
		||||
	<h1>{{ this.$t('share-with', { name }) }}</h1>
 | 
			
		||||
	<div>
 | 
			
		||||
		<mk-signin v-if="!$store.getters.isSignedIn"/>
 | 
			
		||||
		<mk-post-form v-else-if="!posted" :initial-text="text" :instant="true" @posted="posted = true"/>
 | 
			
		||||
		<p v-if="posted" class="posted"><fa icon="check"/></p>
 | 
			
		||||
	</div>
 | 
			
		||||
	<button v-if="posted" class="ui button" @click="close">%i18n:common.close%</button>
 | 
			
		||||
	<button v-if="posted" class="ui button" @click="close">{{ $t('@.close') }}</button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/pages/share.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			name: null,
 | 
			
		||||
 
 | 
			
		||||
@@ -3,18 +3,20 @@
 | 
			
		||||
	<header :class="$style.header">
 | 
			
		||||
		<h1>#{{ $route.params.tag }}</h1>
 | 
			
		||||
	</header>
 | 
			
		||||
	<p :class="$style.empty" v-if="!fetching && empty"><fa icon="search"/> {{ '%i18n:no-posts-found%'.split('{}')[0] }}{{ q }}{{ '%i18n:no-posts-found%'.split('{}')[1] }}</p>
 | 
			
		||||
	<p :class="$style.empty" v-if="!fetching && empty"><fa icon="search"/> {{ $t('no-posts-found', { q }) }}</p>
 | 
			
		||||
	<mk-notes ref="timeline" :class="$style.notes" :more="existMore ? more : null"/>
 | 
			
		||||
</mk-ui>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import Progress from '../../../common/scripts/loading';
 | 
			
		||||
 | 
			
		||||
const limit = 20;
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/pages/tag.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			fetching: true,
 | 
			
		||||
 
 | 
			
		||||
@@ -11,7 +11,7 @@
 | 
			
		||||
			<mk-user-card v-for="user in users" :user="user" :key="user.id"/>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="more" v-if="next">
 | 
			
		||||
			<ui-button inline @click="fetchMore">%i18n:@load-more%</ui-button>
 | 
			
		||||
			<ui-button inline @click="fetchMore">{{ $t('@.load-more') }}</ui-button>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</mk-ui>
 | 
			
		||||
@@ -19,22 +19,14 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import VueI18n from 'vue-i18n';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import parseAcct from '../../../../../misc/acct/parse';
 | 
			
		||||
import Progress from '../../../common/scripts/loading';
 | 
			
		||||
import { lang, locale } from '../../../config';
 | 
			
		||||
 | 
			
		||||
const limit = 16;
 | 
			
		||||
 | 
			
		||||
const i18n = new VueI18n({
 | 
			
		||||
	locale: lang,
 | 
			
		||||
	messages: {
 | 
			
		||||
		[lang]: locale['desktop/views/pages/user-following-or-followers.vue']
 | 
			
		||||
	}
 | 
			
		||||
});
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n,
 | 
			
		||||
	i18n: i18n('desktop/views/pages/user-following-or-followers.vue'),
 | 
			
		||||
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,20 +1,22 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="vahgrswmbzfdlmomxnqftuueyvwaafth">
 | 
			
		||||
	<p class="title"><fa icon="users"/>%i18n:@title%</p>
 | 
			
		||||
	<p class="initializing" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>%i18n:@loading%<mk-ellipsis/></p>
 | 
			
		||||
	<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">%i18n:@no-users%</p>
 | 
			
		||||
	<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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="hozptpaliadatkehcmcayizwzwwctpbc">
 | 
			
		||||
	<p class="title"><fa icon="users"/>%i18n:@title%</p>
 | 
			
		||||
	<p class="initializing" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>%i18n:@loading%<mk-ellipsis/></p>
 | 
			
		||||
	<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"/>
 | 
			
		||||
@@ -12,14 +12,16 @@
 | 
			
		||||
			<mk-follow-button :user="friend"/>
 | 
			
		||||
		</div>
 | 
			
		||||
	</template>
 | 
			
		||||
	<p class="empty" v-if="!fetching && users.length == 0">%i18n:@no-users%</p>
 | 
			
		||||
	<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 {
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@
 | 
			
		||||
			<p class="name">{{ user | userName }}</p>
 | 
			
		||||
			<div>
 | 
			
		||||
				<span class="username"><mk-acct :user="user" :detail="true" /></span>
 | 
			
		||||
				<span v-if="user.isBot" title="%i18n:@is-bot%"><fa icon="robot"/></span>
 | 
			
		||||
				<span v-if="user.isBot" :title="$t('title')"><fa icon="robot"/></span>
 | 
			
		||||
			</div>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
@@ -18,12 +18,12 @@
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="info">
 | 
			
		||||
			<span class="location" v-if="user.host === null && user.profile.location"><fa icon="map-marker"/> {{ user.profile.location }}</span>
 | 
			
		||||
			<span class="birthday" v-if="user.host === null && user.profile.birthday"><fa icon="birthday-cake"/> {{ user.profile.birthday.replace('-', '%i18n:@year%').replace('-', '%i18n:@month%') + '%i18n:@day%' }} ({{ age }}%i18n:@years-old%)</span>
 | 
			
		||||
			<span class="birthday" v-if="user.host === null && user.profile.birthday"><fa icon="birthday-cake"/> {{ user.profile.birthday.replace('-', this.$t('year')).replace('-', this.$t('month')) + this.$t('day') }} ({{ age }}%i18n:@years-old%)</span>
 | 
			
		||||
		</div>
 | 
			
		||||
		<div class="status">
 | 
			
		||||
			<span class="notes-count"><b>{{ user.notesCount | number }}</b>%i18n:@posts%</span>
 | 
			
		||||
			<router-link :to="user | userPage('following')" class="following clickable" @click="showFollowing"><b>{{ user.followingCount | number }}</b>%i18n:@following%</router-link>
 | 
			
		||||
			<router-link :to="user | userPage('followers')" class="followers clickable" @click="showFollowers"><b>{{ user.followersCount | number }}</b>%i18n:@followers%</router-link>
 | 
			
		||||
			<span class="notes-count"><b>{{ user.notesCount | number }}</b>{{ $t('posts') }}</span>
 | 
			
		||||
			<router-link :to="user | userPage('following')" class="following clickable" @click="showFollowing"><b>{{ user.followingCount | number }}</b>{{ $t('following') }}</router-link>
 | 
			
		||||
			<router-link :to="user | userPage('followers')" class="followers clickable" @click="showFollowers"><b>{{ user.followersCount | number }}</b>{{ $t('followers') }}</router-link>
 | 
			
		||||
		</div>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -31,9 +31,11 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
import * as age from 's-age';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/pages/user/user.header.vue'),
 | 
			
		||||
	props: ['user'],
 | 
			
		||||
	computed: {
 | 
			
		||||
		style(): any {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,19 +1,21 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="dzsuvbsrrrwobdxifudxuefculdfiaxd">
 | 
			
		||||
	<p class="title"><fa icon="camera"/>%i18n:@title%</p>
 | 
			
		||||
	<p class="initializing" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>%i18n:@loading%<mk-ellipsis/></p>
 | 
			
		||||
	<p class="title"><fa icon="camera"/>{{ $t('title') }}</p>
 | 
			
		||||
	<p class="initializing" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>{{ $t('loading') }}<mk-ellipsis/></p>
 | 
			
		||||
	<div class="stream" v-if="!fetching && images.length > 0">
 | 
			
		||||
		<div v-for="image in images" class="img"
 | 
			
		||||
			:style="`background-image: url(${image.thumbnailUrl})`"
 | 
			
		||||
		></div>
 | 
			
		||||
	</div>
 | 
			
		||||
	<p class="empty" v-if="!fetching && images.length == 0">%i18n:@no-photos%</p>
 | 
			
		||||
	<p class="empty" v-if="!fetching && images.length == 0">{{ $t('no-photos') }}</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.photos.vue'),
 | 
			
		||||
	props: ['user'],
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
 
 | 
			
		||||
@@ -2,31 +2,33 @@
 | 
			
		||||
<div class="profile" v-if="$store.getters.isSignedIn">
 | 
			
		||||
	<div class="friend-form" v-if="$store.state.i.id != user.id">
 | 
			
		||||
		<mk-follow-button :user="user" size="big"/>
 | 
			
		||||
		<p class="followed" v-if="user.isFollowed">%i18n:@follows-you%</p>
 | 
			
		||||
		<p class="followed" v-if="user.isFollowed">{{ $t('follows-you') }}</p>
 | 
			
		||||
		<p class="stalk" v-if="user.isFollowing">
 | 
			
		||||
			<span v-if="user.isStalking">%i18n:@stalking% <a @click="unstalk"><fa icon="meh"/> %i18n:@unstalk%</a></span>
 | 
			
		||||
			<span v-if="!user.isStalking"><a @click="stalk"><fa icon="user-secret"/> %i18n:@stalk%</a></span>
 | 
			
		||||
			<span v-if="user.isStalking">{{ $t('stalking% <a @click="unstalk"><fa icon="meh"/> %i18n:@unstalk') }}</a></span>
 | 
			
		||||
			<span v-if="!user.isStalking"><a @click="stalk"><fa icon="user-secret"/> {{ $t('stalk') }}</a></span>
 | 
			
		||||
		</p>
 | 
			
		||||
	</div>
 | 
			
		||||
	<div class="action-form">
 | 
			
		||||
		<ui-button @click="user.isMuted ? unmute() : mute()" v-if="$store.state.i.id != user.id">
 | 
			
		||||
			<span v-if="user.isMuted"><fa icon="eye"/> %i18n:@unmute%</span>
 | 
			
		||||
			<span v-else><fa icon="eye-slash"/> %i18n:@mute%</span>
 | 
			
		||||
			<span v-if="user.isMuted"><fa icon="eye"/> {{ $t('unmute') }}</span>
 | 
			
		||||
			<span v-else><fa icon="eye-slash"/> {{ $t('mute') }}</span>
 | 
			
		||||
		</ui-button>
 | 
			
		||||
		<ui-button @click="user.isBlocking ? unblock() : block()" v-if="$store.state.i.id != user.id">
 | 
			
		||||
			<span v-if="user.isBlocking"><fa icon="user"/> %i18n:@unblock%</span>
 | 
			
		||||
			<span v-else><fa icon="user-slash"/> %i18n:@block%</span>
 | 
			
		||||
			<span v-if="user.isBlocking"><fa icon="user"/> {{ $t('unblock') }}</span>
 | 
			
		||||
			<span v-else><fa icon="user-slash"/> {{ $t('block') }}</span>
 | 
			
		||||
		</ui-button>
 | 
			
		||||
		<ui-button @click="list"><fa icon="list"/> %i18n:@push-to-a-list%</ui-button>
 | 
			
		||||
		<ui-button @click="list"><fa icon="list"/> {{ $t('push-to-a-list') }}</ui-button>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
import MkUserListsWindow from '../../components/user-lists-window.vue';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/pages/user/user.profile.vue'),
 | 
			
		||||
	props: ['user'],
 | 
			
		||||
 | 
			
		||||
	methods: {
 | 
			
		||||
@@ -71,7 +73,7 @@ export default Vue.extend({
 | 
			
		||||
		},
 | 
			
		||||
 | 
			
		||||
		block() {
 | 
			
		||||
			if (!window.confirm('%i18n:@block-confirm%')) return;
 | 
			
		||||
			if (!window.confirm(this.$t('block-confirm'))) return;
 | 
			
		||||
			(this as any).api('blocking/create', {
 | 
			
		||||
				userId: this.user.id
 | 
			
		||||
			}).then(() => {
 | 
			
		||||
@@ -101,7 +103,7 @@ export default Vue.extend({
 | 
			
		||||
				});
 | 
			
		||||
				(this as any).apis.dialog({
 | 
			
		||||
					title: 'Done!',
 | 
			
		||||
					text: '%i18n:@list-pushed%'.replace('{user}', this.user.name).replace('{list}', list.title)
 | 
			
		||||
					text: this.$t('list-pushed').replace('{user}', this.user.name).replace('{list}', list.title)
 | 
			
		||||
				});
 | 
			
		||||
			});
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,22 +1,24 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="oh5y2r7l5lx8j6jj791ykeiwgihheguk">
 | 
			
		||||
	<header>
 | 
			
		||||
		<span :data-active="mode == 'default'" @click="mode = 'default'"><fa :icon="['far', 'comment-alt']"/> %i18n:@default%</span>
 | 
			
		||||
		<span :data-active="mode == 'with-replies'" @click="mode = 'with-replies'"><fa icon="comments"/> %i18n:@with-replies%</span>
 | 
			
		||||
		<span :data-active="mode == 'with-media'" @click="mode = 'with-media'"><fa icon="images"/> %i18n:@with-media%</span>
 | 
			
		||||
		<span :data-active="mode == 'default'" @click="mode = 'default'"><fa :icon="['far', 'comment-alt']"/> {{ $t('default') }}</span>
 | 
			
		||||
		<span :data-active="mode == 'with-replies'" @click="mode = 'with-replies'"><fa icon="comments"/> {{ $t('with-replies') }}</span>
 | 
			
		||||
		<span :data-active="mode == 'with-media'" @click="mode = 'with-media'"><fa icon="images"/> {{ $t('with-media') }}</span>
 | 
			
		||||
	</header>
 | 
			
		||||
	<mk-notes ref="timeline" :more="existMore ? more : null">
 | 
			
		||||
		<p class="empty" slot="empty"><fa :icon="['far', 'comments']"/>%i18n:@empty%</p>
 | 
			
		||||
		<p class="empty" slot="empty"><fa :icon="['far', 'comments']"/>{{ $t('empty') }}</p>
 | 
			
		||||
	</mk-notes>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
 | 
			
		||||
const fetchLimit = 10;
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/pages/user/user.timeline.vue'),
 | 
			
		||||
	props: ['user'],
 | 
			
		||||
 | 
			
		||||
	data() {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
<template>
 | 
			
		||||
<mk-ui>
 | 
			
		||||
	<div class="xygkxeaeontfaokvqmiblezmhvhostak" v-if="!fetching">
 | 
			
		||||
		<div class="is-suspended" v-if="user.isSuspended"><fa icon="exclamation-triangle"/> %i18n:@is-suspended%</div>
 | 
			
		||||
		<div class="is-remote" v-if="user.host != null"><fa icon="exclamation-triangle"/> %i18n:common.is-remote-user%<a :href="user.url || user.uri" target="_blank">%i18n:common.view-on-remote%</a></div>
 | 
			
		||||
		<div class="is-suspended" v-if="user.isSuspended"><fa icon="exclamation-triangle"/> {{ $t('@.is-suspended') }}</div>
 | 
			
		||||
		<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>
 | 
			
		||||
		<main>
 | 
			
		||||
			<div class="main">
 | 
			
		||||
				<x-header :user="user"/>
 | 
			
		||||
@@ -20,7 +20,6 @@
 | 
			
		||||
				<x-friends :user="user"/>
 | 
			
		||||
				<x-followers-you-know v-if="$store.getters.isSignedIn && $store.state.i.id != user.id" :user="user"/>
 | 
			
		||||
				<div class="nav"><mk-nav/></div>
 | 
			
		||||
				<p v-if="!user.host">%i18n:@last-used-at%: <b><mk-time :time="user.lastUsedAt"/></b></p>
 | 
			
		||||
			</div>
 | 
			
		||||
		</main>
 | 
			
		||||
	</div>
 | 
			
		||||
@@ -29,6 +28,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../../i18n';
 | 
			
		||||
import parseAcct from '../../../../../../misc/acct/parse';
 | 
			
		||||
import Progress from '../../../../common/scripts/loading';
 | 
			
		||||
import XHeader from './user.header.vue';
 | 
			
		||||
@@ -41,6 +41,7 @@ import XTwitter from './user.twitter.vue';
 | 
			
		||||
import XGithub from './user.github.vue'; // ?MEM: Don't fix the intentional typo. (XGitHub -> `<x-git-hub>`)
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n(),
 | 
			
		||||
	components: {
 | 
			
		||||
		XHeader,
 | 
			
		||||
		XTimeline,
 | 
			
		||||
 
 | 
			
		||||
@@ -17,7 +17,7 @@
 | 
			
		||||
					<h1 v-else><img svg-inline src="../../../../assets/title.svg" :alt="name"></h1>
 | 
			
		||||
 | 
			
		||||
					<div class="info">
 | 
			
		||||
						<span><b>{{ host }}</b> - <span v-html="'%i18n:@powered-by-misskey%'"></span></span>
 | 
			
		||||
						<span><b>{{ host }}</b> - <span v-html="$t('powered-by-misskey')"></span></span>
 | 
			
		||||
						<span class="stats" v-if="stats">
 | 
			
		||||
							<span><fa icon="user"/> {{ stats.originalUsersCount | number }}</span>
 | 
			
		||||
							<span><fa icon="pencil-alt"/> {{ stats.originalNotesCount | number }}</span>
 | 
			
		||||
@@ -25,14 +25,14 @@
 | 
			
		||||
					</div>
 | 
			
		||||
 | 
			
		||||
					<div class="desc">
 | 
			
		||||
						<span class="desc" v-html="description || '%i18n:common.about%'"></span>
 | 
			
		||||
						<a class="about" @click="about">%i18n:@about%</a>
 | 
			
		||||
						<span class="desc" v-html="description || $t('@.about')"></span>
 | 
			
		||||
						<a class="about" @click="about">{{ $t('about') }}</a>
 | 
			
		||||
					</div>
 | 
			
		||||
 | 
			
		||||
					<p class="sign">
 | 
			
		||||
						<span class="signup" @click="signup">%i18n:@signup%</span>
 | 
			
		||||
						<span class="signup" @click="signup">{{ $t('signup') }}</span>
 | 
			
		||||
						<span class="divider">|</span>
 | 
			
		||||
						<span class="signin" @click="signin">%i18n:@signin%</span>
 | 
			
		||||
						<span class="signin" @click="signin">{{ $t('signin') }}</span>
 | 
			
		||||
					</p>
 | 
			
		||||
 | 
			
		||||
					<img src="/assets/ai.png" alt="" title="藍" class="char">
 | 
			
		||||
@@ -40,7 +40,7 @@
 | 
			
		||||
			</div>
 | 
			
		||||
 | 
			
		||||
			<div class="announcements block">
 | 
			
		||||
				<header><fa icon="broadcast-tower"/> %i18n:@announcements%</header>
 | 
			
		||||
				<header><fa icon="broadcast-tower"/> {{ $t('announcements') }}</header>
 | 
			
		||||
				<div v-if="announcements && announcements.length > 0">
 | 
			
		||||
					<div v-for="announcement in announcements">
 | 
			
		||||
						<h1 v-html="announcement.title"></h1>
 | 
			
		||||
@@ -50,7 +50,7 @@
 | 
			
		||||
			</div>
 | 
			
		||||
 | 
			
		||||
			<div class="photos block">
 | 
			
		||||
				<header><fa icon="images"/> %i18n:@photos%</header>
 | 
			
		||||
				<header><fa icon="images"/> {{ $t('photos') }}</header>
 | 
			
		||||
				<div>
 | 
			
		||||
					<div v-for="photo in photos" :style="`background-image: url(${photo.thumbnailUrl})`"></div>
 | 
			
		||||
				</div>
 | 
			
		||||
@@ -76,14 +76,14 @@
 | 
			
		||||
				</div>
 | 
			
		||||
 | 
			
		||||
				<div class="tl block">
 | 
			
		||||
					<header><fa :icon="['far', 'comment-alt']"/> %i18n:@timeline%</header>
 | 
			
		||||
					<header><fa :icon="['far', 'comment-alt']"/> {{ $t('timeline') }}</header>
 | 
			
		||||
					<div>
 | 
			
		||||
						<mk-welcome-timeline class="tl" :max="20"/>
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
 | 
			
		||||
				<div class="info block">
 | 
			
		||||
					<header><fa icon="info-circle"/> %i18n:@info%</header>
 | 
			
		||||
					<header><fa icon="info-circle"/> {{ $t('info') }}</header>
 | 
			
		||||
					<div>
 | 
			
		||||
						<div v-if="meta" class="body">
 | 
			
		||||
							<p>Version: <b>{{ meta.version }}</b></p>
 | 
			
		||||
@@ -97,50 +97,50 @@
 | 
			
		||||
 | 
			
		||||
	<modal name="about" class="about modal" width="800px" height="auto" scrollable>
 | 
			
		||||
		<article class="fpdezooorhntlzyeszemrsqdlgbysvxq">
 | 
			
		||||
			<h1>%i18n:common.intro.title%</h1>
 | 
			
		||||
			<p v-html="'%i18n:common.intro.about%'"></p>
 | 
			
		||||
			<h1>{{ $t('@.intro.title') }}</h1>
 | 
			
		||||
			<p v-html="this.$t('@.intro.about')"></p>
 | 
			
		||||
			<section>
 | 
			
		||||
				<h2>%i18n:common.intro.features%</h2>
 | 
			
		||||
				<h2>{{ $t('@.intro.features') }}</h2>
 | 
			
		||||
				<section>
 | 
			
		||||
					<div class="body">
 | 
			
		||||
						<h3>%i18n:common.intro.rich-contents%</h3>
 | 
			
		||||
						<p v-html="'%i18n:common.intro.rich-contents-desc%'"></p>
 | 
			
		||||
						<h3>{{ $t('@.intro.rich-contents') }}</h3>
 | 
			
		||||
						<p v-html="this.$t('@.intro.rich-contents-desc')"></p>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="image"><img src="/assets/about/post.png" alt=""></div>
 | 
			
		||||
				</section>
 | 
			
		||||
				<section>
 | 
			
		||||
					<div class="body">
 | 
			
		||||
						<h3>%i18n:common.intro.reaction%</h3>
 | 
			
		||||
						<p v-html="'%i18n:common.intro.reaction-desc%'"></p>
 | 
			
		||||
						<h3>{{ $t('@.intro.reaction') }}</h3>
 | 
			
		||||
						<p v-html="this.$t('@.intro.reaction-desc')"></p>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="image"><img src="/assets/about/reaction.png" alt=""></div>
 | 
			
		||||
				</section>
 | 
			
		||||
				<section>
 | 
			
		||||
					<div class="body">
 | 
			
		||||
						<h3>%i18n:common.intro.ui%</h3>
 | 
			
		||||
						<p v-html="'%i18n:common.intro.ui-desc%'"></p>
 | 
			
		||||
						<h3>{{ $t('@.intro.ui') }}</h3>
 | 
			
		||||
						<p v-html="this.$t('@.intro.ui-desc')"></p>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="image"><img src="/assets/about/ui.png" alt=""></div>
 | 
			
		||||
				</section>
 | 
			
		||||
				<section>
 | 
			
		||||
					<div class="body">
 | 
			
		||||
						<h3>%i18n:common.intro.drive%</h3>
 | 
			
		||||
						<p v-html="'%i18n:common.intro.drive-desc%'"></p>
 | 
			
		||||
						<h3>{{ $t('@.intro.drive') }}</h3>
 | 
			
		||||
						<p v-html="this.$t('@.intro.drive-desc')"></p>
 | 
			
		||||
					</div>
 | 
			
		||||
					<div class="image"><img src="/assets/about/drive.png" alt=""></div>
 | 
			
		||||
				</section>
 | 
			
		||||
			</section>
 | 
			
		||||
			<p v-html="'%i18n:common.intro.outro%'"></p>
 | 
			
		||||
			<p v-html="this.$t('@.intro.outro')"></p>
 | 
			
		||||
		</article>
 | 
			
		||||
	</modal>
 | 
			
		||||
 | 
			
		||||
	<modal name="signup" class="modal" width="450px" height="auto" scrollable>
 | 
			
		||||
		<header class="formHeader">%i18n:@signup%</header>
 | 
			
		||||
		<header class="formHeader">{{ $t('signup') }}</header>
 | 
			
		||||
		<mk-signup class="form"/>
 | 
			
		||||
	</modal>
 | 
			
		||||
 | 
			
		||||
	<modal name="signin" class="modal" width="450px" height="auto" scrollable>
 | 
			
		||||
		<header class="formHeader">%i18n:@signin%</header>
 | 
			
		||||
		<header class="formHeader">{{ $t('signin') }}</header>
 | 
			
		||||
		<mk-signin class="form"/>
 | 
			
		||||
	</modal>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -148,10 +148,12 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import Vue from 'vue';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import { host, copyright } from '../../../config';
 | 
			
		||||
import { concat } from '../../../../../prelude/array';
 | 
			
		||||
 | 
			
		||||
export default Vue.extend({
 | 
			
		||||
	i18n: i18n('desktop/views/pages/welcome.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			meta: null,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mkw-messaging">
 | 
			
		||||
	<mk-widget-container :show-header="props.design == 0">
 | 
			
		||||
		<template slot="header"><fa icon="comments"/>%i18n:@title%</template>
 | 
			
		||||
		<template slot="header"><fa icon="comments"/>{{ $t('title') }}</template>
 | 
			
		||||
		<button slot="func" @click="add"><fa icon="plus"/></button>
 | 
			
		||||
 | 
			
		||||
		<mk-messaging ref="index" compact @navigate="navigate"/>
 | 
			
		||||
@@ -11,6 +11,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import define from '../../../common/define-widget';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
import MkMessagingRoomWindow from '../components/messaging-room-window.vue';
 | 
			
		||||
import MkMessagingWindow from '../components/messaging-window.vue';
 | 
			
		||||
 | 
			
		||||
@@ -20,6 +21,7 @@ export default define({
 | 
			
		||||
		design: 0
 | 
			
		||||
	})
 | 
			
		||||
}).extend({
 | 
			
		||||
	i18n: i18n('desktop/views/widgets/messaging.vue'),
 | 
			
		||||
	methods: {
 | 
			
		||||
		navigate(user) {
 | 
			
		||||
			(this as any).os.new(MkMessagingRoomWindow, {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mkw-notifications">
 | 
			
		||||
	<mk-widget-container :show-header="!props.compact">
 | 
			
		||||
		<template slot="header"><fa :icon="['far', 'bell']"/>%i18n:@title%</template>
 | 
			
		||||
		<!-- <button slot="func" title="%i18n:@settings%" @click="settings"><fa icon="cog"/></button> -->
 | 
			
		||||
		<template slot="header"><fa :icon="['far', 'bell']"/>{{ $t('title') }}</template>
 | 
			
		||||
		<!-- <button slot="func" :title="$t('title')" @click="settings"><fa icon="cog"/></button> -->
 | 
			
		||||
 | 
			
		||||
		<mk-notifications :class="$style.notifications"/>
 | 
			
		||||
	</mk-widget-container>
 | 
			
		||||
@@ -11,12 +11,15 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import define from '../../../common/define-widget';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default define({
 | 
			
		||||
	name: 'notifications',
 | 
			
		||||
	props: () => ({
 | 
			
		||||
		compact: false
 | 
			
		||||
	})
 | 
			
		||||
}).extend({
 | 
			
		||||
	i18n: i18n('desktop/views/widgets/notifications.vue'),
 | 
			
		||||
	methods: {
 | 
			
		||||
		settings() {
 | 
			
		||||
			alert('not implemented yet');
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,8 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mkw-polls">
 | 
			
		||||
	<mk-widget-container :show-header="!props.compact">
 | 
			
		||||
		<template slot="header"><fa icon="chart-pie"/>%i18n:@title%</template>
 | 
			
		||||
		<button slot="func" title="%i18n:@refresh%" @click="fetch"><fa icon="sync"/></button>
 | 
			
		||||
		<template slot="header"><fa icon="chart-pie"/>{{ $t('title') }}</template>
 | 
			
		||||
		<button slot="func" :title="$t('title')" @click="fetch"><fa icon="sync"/></button>
 | 
			
		||||
 | 
			
		||||
		<div class="mkw-polls--body">
 | 
			
		||||
			<div class="poll" v-if="!fetching && poll != null">
 | 
			
		||||
@@ -10,8 +10,8 @@
 | 
			
		||||
				<p v-if="!poll.text"><router-link :to="poll | notePage"><fa icon="link"/></router-link></p>
 | 
			
		||||
				<mk-poll :note="poll"/>
 | 
			
		||||
			</div>
 | 
			
		||||
			<p class="empty" v-if="!fetching && poll == null">%i18n:@nothing%</p>
 | 
			
		||||
			<p class="fetching" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>%i18n:common.loading%<mk-ellipsis/></p>
 | 
			
		||||
			<p class="empty" v-if="!fetching && poll == null">{{ $t('nothing') }}</p>
 | 
			
		||||
			<p class="fetching" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p>
 | 
			
		||||
		</div>
 | 
			
		||||
	</mk-widget-container>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -19,6 +19,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import define from '../../../common/define-widget';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default define({
 | 
			
		||||
	name: 'polls',
 | 
			
		||||
@@ -26,6 +27,7 @@ export default define({
 | 
			
		||||
		compact: false
 | 
			
		||||
	})
 | 
			
		||||
}).extend({
 | 
			
		||||
	i18n: i18n('desktop/views/widgets/polls.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			poll: null,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,21 +1,24 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mkw-post-form">
 | 
			
		||||
	<template v-if="props.design == 0">
 | 
			
		||||
		<p class="title"><fa icon="pencil-alt"/>%i18n:@title%</p>
 | 
			
		||||
		<p class="title"><fa icon="pencil-alt"/>{{ $t('title') }}</p>
 | 
			
		||||
	</template>
 | 
			
		||||
	<textarea :disabled="posting" v-model="text" @keydown="onKeydown" :placeholder="placeholder"></textarea>
 | 
			
		||||
	<button @click="post" :disabled="posting">%i18n:@note%</button>
 | 
			
		||||
	<button @click="post" :disabled="posting">{{ $t('note') }}</button>
 | 
			
		||||
</div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import define from '../../../common/define-widget';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default define({
 | 
			
		||||
	name: 'post-form',
 | 
			
		||||
	props: () => ({
 | 
			
		||||
		design: 0
 | 
			
		||||
	})
 | 
			
		||||
}).extend({
 | 
			
		||||
	i18n: i18n('desktop/views/widgets/post-form.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			posting: false,
 | 
			
		||||
@@ -25,12 +28,12 @@ export default define({
 | 
			
		||||
	computed: {
 | 
			
		||||
		placeholder(): string {
 | 
			
		||||
			const xs = [
 | 
			
		||||
				'%i18n:common.note-placeholders.a%',
 | 
			
		||||
				'%i18n:common.note-placeholders.b%',
 | 
			
		||||
				'%i18n:common.note-placeholders.c%',
 | 
			
		||||
				'%i18n:common.note-placeholders.d%',
 | 
			
		||||
				'%i18n:common.note-placeholders.e%',
 | 
			
		||||
				'%i18n:common.note-placeholders.f%'
 | 
			
		||||
				this.$t('@.note-placeholders.a'),
 | 
			
		||||
				this.$t('@.note-placeholders.b'),
 | 
			
		||||
				this.$t('@.note-placeholders.c'),
 | 
			
		||||
				this.$t('@.note-placeholders.d'),
 | 
			
		||||
				this.$t('@.note-placeholders.e'),
 | 
			
		||||
				this.$t('@.note-placeholders.f')
 | 
			
		||||
			];
 | 
			
		||||
			return xs[Math.floor(Math.random() * xs.length)];
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,13 +7,13 @@
 | 
			
		||||
		>
 | 
			
		||||
			<div class="banner"
 | 
			
		||||
				:style="$store.state.i.bannerUrl ? `background-image: url(${$store.state.i.bannerUrl})` : ''"
 | 
			
		||||
				title="%i18n:@update-banner%"
 | 
			
		||||
				:title="$t('update-banner')"
 | 
			
		||||
				@click="() => os.apis.updateBanner()"
 | 
			
		||||
			></div>
 | 
			
		||||
			<mk-avatar class="avatar" :user="$store.state.i"
 | 
			
		||||
				:disable-link="true"
 | 
			
		||||
				@click="() => os.apis.updateAvatar()"
 | 
			
		||||
				title="%i18n:@update-avatar%"
 | 
			
		||||
				:title="$t('update-avatar')"
 | 
			
		||||
			/>
 | 
			
		||||
			<router-link class="name" :to="$store.state.i | userPage">{{ $store.state.i | userName }}</router-link>
 | 
			
		||||
			<p class="username">@{{ $store.state.i | acct }}</p>
 | 
			
		||||
@@ -24,6 +24,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import define from '../../../common/define-widget';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default define({
 | 
			
		||||
	name: 'profile',
 | 
			
		||||
@@ -31,6 +32,7 @@ export default define({
 | 
			
		||||
		design: 0
 | 
			
		||||
	})
 | 
			
		||||
}).extend({
 | 
			
		||||
	i18n: i18n('desktop/views/widgets/profile.vue'),
 | 
			
		||||
	methods: {
 | 
			
		||||
		func() {
 | 
			
		||||
			if (this.props.design == 2) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,16 +1,16 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mkw-trends">
 | 
			
		||||
	<mk-widget-container :show-header="!props.compact">
 | 
			
		||||
		<template slot="header"><fa icon="fire"/>%i18n:@title%</template>
 | 
			
		||||
		<button slot="func" title="%i18n:@refresh%" @click="fetch"><fa icon="sync"/></button>
 | 
			
		||||
		<template slot="header"><fa icon="fire"/>{{ $t('title') }}</template>
 | 
			
		||||
		<button slot="func" :title="$t('title')" @click="fetch"><fa icon="sync"/></button>
 | 
			
		||||
 | 
			
		||||
		<div class="mkw-trends--body">
 | 
			
		||||
			<p class="fetching" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>%i18n:common.loading%<mk-ellipsis/></p>
 | 
			
		||||
			<p class="fetching" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p>
 | 
			
		||||
			<div class="note" v-else-if="note != null">
 | 
			
		||||
				<p class="text"><router-link :to="note | notePage">{{ note.text }}</router-link></p>
 | 
			
		||||
				<p class="author">―<router-link :to="note.user | userPage">@{{ note.user | acct }}</router-link></p>
 | 
			
		||||
			</div>
 | 
			
		||||
			<p class="empty" v-else>%i18n:@nothing%</p>
 | 
			
		||||
			<p class="empty" v-else>{{ $t('nothing') }}</p>
 | 
			
		||||
		</div>
 | 
			
		||||
	</mk-widget-container>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -18,6 +18,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import define from '../../../common/define-widget';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
export default define({
 | 
			
		||||
	name: 'trends',
 | 
			
		||||
@@ -25,6 +26,7 @@ export default define({
 | 
			
		||||
		compact: false
 | 
			
		||||
	})
 | 
			
		||||
}).extend({
 | 
			
		||||
	i18n: i18n('desktop/views/widgets/trends.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			note: null,
 | 
			
		||||
 
 | 
			
		||||
@@ -1,11 +1,11 @@
 | 
			
		||||
<template>
 | 
			
		||||
<div class="mkw-users">
 | 
			
		||||
	<mk-widget-container :show-header="!props.compact">
 | 
			
		||||
		<template slot="header"><fa icon="users"/>%i18n:@title%</template>
 | 
			
		||||
		<button slot="func" title="%i18n:@refresh%" @click="refresh"><fa icon="sync"/></button>
 | 
			
		||||
		<template slot="header"><fa icon="users"/>{{ $t('title') }}</template>
 | 
			
		||||
		<button slot="func" :title="$t('title')" @click="refresh"><fa icon="sync"/></button>
 | 
			
		||||
 | 
			
		||||
		<div class="mkw-users--body">
 | 
			
		||||
			<p class="fetching" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>%i18n:common.loading%<mk-ellipsis/></p>
 | 
			
		||||
			<p class="fetching" v-if="fetching"><fa icon="spinner .pulse" fixed-width/>{{ $t('@.loading') }}<mk-ellipsis/></p>
 | 
			
		||||
			<template v-else-if="users.length != 0">
 | 
			
		||||
				<div class="user" v-for="_user in users">
 | 
			
		||||
					<mk-avatar class="avatar" :user="_user"/>
 | 
			
		||||
@@ -15,7 +15,7 @@
 | 
			
		||||
					</div>
 | 
			
		||||
				</div>
 | 
			
		||||
			</template>
 | 
			
		||||
			<p class="empty" v-else>%i18n:@no-one%</p>
 | 
			
		||||
			<p class="empty" v-else>{{ $t('no-one') }}</p>
 | 
			
		||||
		</div>
 | 
			
		||||
	</mk-widget-container>
 | 
			
		||||
</div>
 | 
			
		||||
@@ -23,6 +23,7 @@
 | 
			
		||||
 | 
			
		||||
<script lang="ts">
 | 
			
		||||
import define from '../../../common/define-widget';
 | 
			
		||||
import i18n from '../../../i18n';
 | 
			
		||||
 | 
			
		||||
const limit = 3;
 | 
			
		||||
 | 
			
		||||
@@ -32,6 +33,7 @@ export default define({
 | 
			
		||||
		compact: false
 | 
			
		||||
	})
 | 
			
		||||
}).extend({
 | 
			
		||||
	i18n: i18n('desktop/views/widgets/users.vue'),
 | 
			
		||||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			users: [],
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user