Refactoring of i18n (#3165)

Refactoring of i18n
This commit is contained in:
syuilo
2018-11-09 03:44:35 +09:00
committed by GitHub
parent 21303bd06a
commit 25a69ec1b6
211 changed files with 1825 additions and 1624 deletions

View File

@@ -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 {

View File

@@ -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

View File

@@ -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')
]
};
},

View File

@@ -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

View File

@@ -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: {

View File

@@ -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
},

View File

@@ -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 {

View File

@@ -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')
}]
});
},

View File

@@ -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', {

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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,

View File

@@ -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: [],

View File

@@ -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')
},

View File

@@ -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')
}]
});
},

View File

@@ -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

View File

@@ -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,

View File

@@ -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,

View File

@@ -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 {

View File

@@ -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, {

View File

@@ -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
},

View File

@@ -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
},

View File

@@ -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;
});
}

View File

@@ -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;
});
}

View File

@@ -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,

View File

@@ -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;
});

View File

@@ -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 {

View File

@@ -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,

View File

@@ -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,

View File

@@ -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;
});

View File

@@ -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,

View File

@@ -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'));
});
}
}

View File

@@ -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,

View File

@@ -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

View File

@@ -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() {

View File

@@ -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>

View File

@@ -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,

View File

@@ -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'

View File

@@ -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

View File

@@ -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,

View File

@@ -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

View File

@@ -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();

View File

@@ -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: ''

View File

@@ -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,

View File

@@ -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,

View File

@@ -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

View File

@@ -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],

View File

@@ -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,